diff --git a/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java b/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java index 1fb8c5fcc0ba..4a16578615b8 100644 --- a/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java +++ b/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticCode.java @@ -72,6 +72,7 @@ public enum DiagnosticCode { ABSTRACT_OBJECT_FUNCTION_CANNOT_HAVE_BODY("abstract.object.function.cannot.have.body"), PRIVATE_OBJECT_CONSTRUCTOR("private.object.constructor"), PRIVATE_FIELD_ABSTRACT_OBJECT("private.field.abstract.object"), + FIELD_WITH_DEFAULT_VALUE_ABSTRACT_OBJECT("field.with.default.value.abstract.object"), PRIVATE_FUNC_ABSTRACT_OBJECT("private.function.abstract.object"), EXTERN_FUNC_ABSTRACT_OBJECT("extern.function.abstract.object"), RESOURCE_FUNCTION_CANNOT_BE_EXTERN("resource.function.cannot.be.extern"), @@ -104,6 +105,7 @@ public enum DiagnosticCode { EXPLICIT_WORKER_CANNOT_BE_DEFAULT("explicit.worker.cannot.be.default"), INVALID_MULTIPLE_FORK_JOIN_SEND("worker.multiple.fork.join.send"), INCOMPATIBLE_TYPE_REFERENCE("incompatible.type.reference"), + INCOMPATIBLE_TYPE_REFERENCE_NON_PUBLIC_MEMBERS("incompatible.type.reference.non.public.members"), INCOMPATIBLE_RECORD_TYPE_REFERENCE("incompatible.record.type.reference"), REDECLARED_TYPE_REFERENCE("redeclared.type.reference"), REDECLARED_FUNCTION_FROM_TYPE_REFERENCE("redeclared.function.from.type.reference"), diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SemanticAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SemanticAnalyzer.java index 7ebf19c8232a..5332dbbb1fae 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SemanticAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SemanticAnalyzer.java @@ -377,8 +377,14 @@ public void visit(BLangObjectTypeNode objectTypeNode) { boolean isAbstract = objectTypeNode.flagSet.contains(Flag.ABSTRACT); objectTypeNode.fields.forEach(field -> { analyzeDef(field, objectEnv); - if (isAbstract && field.flagSet.contains(Flag.PRIVATE)) { - this.dlog.error(field.pos, DiagnosticCode.PRIVATE_FIELD_ABSTRACT_OBJECT, field.symbol.name); + if (isAbstract) { + if (field.flagSet.contains(Flag.PRIVATE)) { + this.dlog.error(field.pos, DiagnosticCode.PRIVATE_FIELD_ABSTRACT_OBJECT, field.symbol.name); + } + + if (field.expr != null) { + this.dlog.error(field.expr.pos, DiagnosticCode.FIELD_WITH_DEFAULT_VALUE_ABSTRACT_OBJECT); + } } }); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java index 08547d5e4ac0..3ed1bd6932c5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java @@ -58,6 +58,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.types.BField; import org.wso2.ballerinalang.compiler.semantics.model.types.BFutureType; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; +import org.wso2.ballerinalang.compiler.semantics.model.types.BObjectType; import org.wso2.ballerinalang.compiler.semantics.model.types.BRecordType; import org.wso2.ballerinalang.compiler.semantics.model.types.BServiceType; import org.wso2.ballerinalang.compiler.semantics.model.types.BStructureType; @@ -1284,6 +1285,7 @@ private void defineMembers(List typeDefNodes, SymbolEnv pkg defineNode(f, objMethodsEnv); }); + List referencedFunctions = new ArrayList<>(); // Add the attached functions of the referenced types to this object. // Here it is assumed that all the attached functions of the referred type are // resolved by the time we reach here. It is achieved by ordering the typeDefs @@ -1295,7 +1297,7 @@ private void defineMembers(List typeDefNodes, SymbolEnv pkg List functions = ((BObjectTypeSymbol) typeRef.type.tsymbol).attachedFuncs; for (BAttachedFunction function : functions) { - defineReferencedFunction(typeDef, objMethodsEnv, typeRef, function); + defineReferencedFunction(typeDef, objMethodsEnv, typeRef, function, referencedFunctions); } } } else if (typeDef.symbol.kind == SymbolKind.RECORD) { @@ -1688,6 +1690,7 @@ private void createDummyTypeDefSymbol(TypeDefinition typeDefNode, SymbolEnv env) private void resolveReferencedFields(BLangStructureTypeNode structureTypeNode, SymbolEnv typeDefEnv) { List referencedTypes = new ArrayList<>(); + List invalidTypeRefs = new ArrayList<>(); // Get the inherited fields from the type references structureTypeNode.referencedFields = structureTypeNode.typeRefs.stream().flatMap(typeRef -> { BType referredType = symResolver.resolveTypeNode(typeRef, typeDefEnv); @@ -1698,13 +1701,28 @@ private void resolveReferencedFields(BLangStructureTypeNode structureTypeNode, S // Check for duplicate type references if (referencedTypes.contains(referredType.tsymbol)) { dlog.error(typeRef.pos, DiagnosticCode.REDECLARED_TYPE_REFERENCE, typeRef); + invalidTypeRefs.add(typeRef); return Stream.empty(); } - if (structureTypeNode.type.tag == TypeTags.OBJECT && (referredType.tag != TypeTags.OBJECT || !Symbols - .isFlagOn(referredType.tsymbol.flags, Flags.ABSTRACT))) { - dlog.error(typeRef.pos, DiagnosticCode.INCOMPATIBLE_TYPE_REFERENCE, typeRef); - return Stream.empty(); + if (structureTypeNode.type.tag == TypeTags.OBJECT) { + if (referredType.tag != TypeTags.OBJECT || + !Symbols.isFlagOn(referredType.tsymbol.flags, Flags.ABSTRACT)) { + dlog.error(typeRef.pos, DiagnosticCode.INCOMPATIBLE_TYPE_REFERENCE, typeRef); + invalidTypeRefs.add(typeRef); + return Stream.empty(); + } + + BObjectType objectType = (BObjectType) referredType; + if (structureTypeNode.type.tsymbol.owner != referredType.tsymbol.owner) { + if (objectType.fields.stream().anyMatch(field -> !Symbols.isPublic(field.symbol)) || + ((BObjectTypeSymbol) objectType.tsymbol).attachedFuncs.stream() + .anyMatch(func -> !Symbols.isPublic(func.symbol))) { + dlog.error(typeRef.pos, DiagnosticCode.INCOMPATIBLE_TYPE_REFERENCE_NON_PUBLIC_MEMBERS, typeRef); + invalidTypeRefs.add(typeRef); + return Stream.empty(); + } + } } if (structureTypeNode.type.tag == TypeTags.RECORD && referredType.tag != TypeTags.RECORD) { @@ -1724,15 +1742,23 @@ private void resolveReferencedFields(BLangStructureTypeNode structureTypeNode, S return var; }); }).collect(Collectors.toList()); + structureTypeNode.typeRefs.removeAll(invalidTypeRefs); } private void defineReferencedFunction(BLangTypeDefinition typeDef, SymbolEnv objEnv, BLangType typeRef, - BAttachedFunction referencedFunc) { + BAttachedFunction referencedFunc, List referencedFunctions) { + String referencedFuncName = referencedFunc.funcName.value; Name funcName = names.fromString( - Symbols.getAttachedFuncSymbolName(typeDef.symbol.name.value, referencedFunc.funcName.value)); + Symbols.getAttachedFuncSymbolName(typeDef.symbol.name.value, referencedFuncName)); BSymbol matchingObjFuncSym = symResolver.lookupSymbol(objEnv, funcName, SymTag.VARIABLE); if (matchingObjFuncSym != symTable.notFoundSymbol) { + if (referencedFunctions.contains(referencedFuncName)) { + dlog.error(typeRef.pos, DiagnosticCode.REDECLARED_SYMBOL, referencedFuncName); + return; + } + referencedFunctions.add(referencedFuncName); + if (Symbols.isFunctionDeclaration(matchingObjFuncSym) && Symbols.isFunctionDeclaration( referencedFunc.symbol)) { Optional matchingFunc = ((BLangObjectTypeNode) typeDef.typeNode) @@ -1791,7 +1817,10 @@ private boolean hasSameFunctionSignature(BInvokableSymbol attachedFuncSym, BInvo List params = referencedFuncSym.params; for (int i = 0; i < params.size(); i++) { - if (!params.get(i).name.value.equals(attachedFuncSym.params.get(i).name.value)) { + BVarSymbol referencedFuncParam = params.get(i); + BVarSymbol attachedFuncParam = attachedFuncSym.params.get(i); + if (!referencedFuncParam.name.value.equals(attachedFuncParam.name.value) || + !hasSameVisibilityModifier(referencedFuncParam.flags, attachedFuncParam.flags)) { return false; } } @@ -1822,7 +1851,8 @@ private String getCompleteFunctionSignature(BInvokableSymbol funcSymbol) { signatureBuilder.append(visibilityModifier).append("function ") .append(funcSymbol.name.value.split("\\.")[1]); - funcSymbol.params.forEach(param -> paramListBuilder.add(param.type.toString() + " " + param.name.value)); + funcSymbol.params.forEach(param -> paramListBuilder.add( + (Symbols.isPublic(param) ? "public " : "") + param.type.toString() + " " + param.name.value)); if (funcSymbol.restParam != null) { paramListBuilder.add(((BArrayType) funcSymbol.restParam.type).eType.toString() + "... " + diff --git a/compiler/ballerina-lang/src/main/resources/compiler.properties b/compiler/ballerina-lang/src/main/resources/compiler.properties index 5067a32af7fd..b1b12b46247a 100644 --- a/compiler/ballerina-lang/src/main/resources/compiler.properties +++ b/compiler/ballerina-lang/src/main/resources/compiler.properties @@ -718,6 +718,9 @@ error.private.object.constructor=\ error.private.field.abstract.object=\ abstract object field: ''{0}'' can not be declared as private +error.field.with.default.value.abstract.object=\ + fields with default values are not yet supported with abstract objects + error.private.function.abstract.object=\ interface function: ''{0}'' of abstract object ''{1}'' can not be declared as private @@ -742,6 +745,9 @@ error.extern.function.abstract.object=\ error.incompatible.type.reference=\ incompatible types: ''{0}'' is not an abstract object +error.incompatible.type.reference.non.public.members=\ + incompatible type reference ''{0}'': a referenced object cannot have non-public fields or methods + error.incompatible.record.type.reference=\ incompatible types: ''{0}'' is not a record diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/delay-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/delay-window.bal index 8f352a3fb1ae..06a849ecdf8e 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/delay-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/delay-window.bal @@ -142,7 +142,7 @@ public type DelayWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/external-time-batch-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/external-time-batch-window.bal index 2890ab138ae2..df828796fc44 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/external-time-batch-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/external-time-batch-window.bal @@ -256,7 +256,7 @@ public type ExternalTimeBatchWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/external-time-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/external-time-window.bal index d837d0b90070..fe2705cb46f1 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/external-time-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/external-time-window.bal @@ -137,7 +137,7 @@ public type ExternalTimeWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/hopping-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/hopping-window.bal index e97362400be7..68e34f64823f 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/hopping-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/hopping-window.bal @@ -158,7 +158,7 @@ public type HoppingWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/length-batch-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/length-batch-window.bal index 4d0853b67491..456bf268a98a 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/length-batch-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/length-batch-window.bal @@ -134,7 +134,7 @@ public type LengthBatchWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/length-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/length-window.bal index c271af132e9c..819ffd2c87db 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/length-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/length-window.bal @@ -100,7 +100,7 @@ public type LengthWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/sort-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/sort-window.bal index 2901dddb6545..f4bbeb7e8b11 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/sort-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/sort-window.bal @@ -194,7 +194,7 @@ public type SortWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/time-accumulating-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/time-accumulating-window.bal index abf004ec65c7..b948769810d1 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/time-accumulating-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/time-accumulating-window.bal @@ -140,7 +140,7 @@ public type TimeAccumulatingWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/time-batch-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/time-batch-window.bal index c2dffee9a863..67aa77ca691f 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/time-batch-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/time-batch-window.bal @@ -142,7 +142,7 @@ public type TimeBatchWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/time-length-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/time-length-window.bal index 3018f688816a..0e93976afa46 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/time-length-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/time-length-window.bal @@ -160,7 +160,7 @@ public type TimeLengthWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/time-order-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/time-order-window.bal index b5296219ab2a..375fa75b0ca4 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/time-order-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/time-order-window.bal @@ -189,7 +189,7 @@ public type TimeOrderWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/time-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/time-window.bal index e8c5f37d70aa..ab67ee3844fd 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/time-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/time-window.bal @@ -139,7 +139,7 @@ public type TimeWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/streams/src/main/ballerina/src/streams/window/unique-length-window.bal b/stdlib/streams/src/main/ballerina/src/streams/window/unique-length-window.bal index 767ee7503b9a..bc5240ed8719 100644 --- a/stdlib/streams/src/main/ballerina/src/streams/window/unique-length-window.bal +++ b/stdlib/streams/src/main/ballerina/src/streams/window/unique-length-window.bal @@ -168,7 +168,7 @@ public type UniqueLengthWindow object { public function getCandidateEvents( StreamEvent originEvent, (function (map e1Data, map e2Data) returns boolean)? conditionFunc, - boolean isLHSTrigger = true) + public boolean isLHSTrigger = true) returns @tainted [StreamEvent?, StreamEvent?][] { [StreamEvent?, StreamEvent?][] events = []; int i = 0; diff --git a/stdlib/transactions/src/main/ballerina/src/transactions/2pc_participant.bal b/stdlib/transactions/src/main/ballerina/src/transactions/2pc_participant.bal index 722ae0c705be..c2fcdbfccf91 100644 --- a/stdlib/transactions/src/main/ballerina/src/transactions/2pc_participant.bal +++ b/stdlib/transactions/src/main/ballerina/src/transactions/2pc_participant.bal @@ -37,7 +37,7 @@ public type UProtocol LocalProtocol|RemoteProtocol; type Participant abstract object { - string participantId = ""; + string participantId; function prepare(string protocol) returns [(PrepareResult|error)?, Participant]; diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/AbstractObjectTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/AbstractObjectTest.java index 900615b01bb7..244511b02ddb 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/AbstractObjectTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/AbstractObjectTest.java @@ -44,7 +44,7 @@ public void setup() { public void testAbstractObjectNegative() { CompileResult negativeResult = BCompileUtil.compile("test-src/object/abstract-object-negative.bal"); int index = 0; - Assert.assertEquals(negativeResult.getErrorCount(), 11); + Assert.assertEquals(negativeResult.getErrorCount(), 12); BAssertUtil.validateError(negativeResult, index++, "cannot initialize abstract object 'Person1'", 3, 18); BAssertUtil.validateError(negativeResult, index++, "cannot initialize abstract object 'Person2'", 4, 18); BAssertUtil.validateError(negativeResult, index++, "cannot initialize abstract object 'Person1'", 8, 18); @@ -61,8 +61,10 @@ public void testAbstractObjectNegative() { "'Person6' can not be declared as private", 61, 5); BAssertUtil.validateError(negativeResult, index++, "interface function: 'getName' of abstract object 'Foo' " + "can not be declared as private", 65, 5); - BAssertUtil.validateError(negativeResult, index, + BAssertUtil.validateError(negativeResult, index++, "external function: 'getName' not allowed in abstract object 'Person7'", 78, 5); + BAssertUtil.validateError(negativeResult, index, + "fields with default values are not yet supported with abstract objects", 83, 18); } @Test diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/ObjectTypeReferenceTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/ObjectTypeReferenceTest.java index 20b74f4de754..d46a0725aaea 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/ObjectTypeReferenceTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/object/ObjectTypeReferenceTest.java @@ -44,7 +44,7 @@ public void setup() { @Test public void testSimpleObjectTypeReferenceNegative_1() { CompileResult negativeResult = BCompileUtil.compile("test-src/object/object-type-reference-1-negative.bal"); - Assert.assertEquals(negativeResult.getErrorCount(), 22); + Assert.assertEquals(negativeResult.getErrorCount(), 23); int i = 0; BAssertUtil.validateError(negativeResult, i++, "uninitialized field 'age'", 27, 6); BAssertUtil.validateError(negativeResult, i++, "uninitialized field 'name'", 27, 6); @@ -72,7 +72,8 @@ public void testSimpleObjectTypeReferenceNegative_1() { "function through referenced type 'ObjectWithRedeclaredFunction_1'", 125, 6); BAssertUtil.validateError(negativeResult, i++, "redeclared symbol 'x'", 134, 6); BAssertUtil.validateError(negativeResult, i++, "unknown type 'Baz'", 142, 6); - BAssertUtil.validateError(negativeResult, i, "unknown type 'Tar'", 146, 6); + BAssertUtil.validateError(negativeResult, i++, "unknown type 'Tar'", 146, 6); + BAssertUtil.validateError(negativeResult, i, "redeclared symbol 'xyz'", 167, 6); } @Test @@ -151,31 +152,51 @@ public void testTypeReferencedFunctionImplementation() { CompileResult result = BCompileUtil.compile("test-src/object/object_func_reference_neg.bal"); int index = 0; - Assert.assertEquals(result.getErrorCount(), 7); + Assert.assertEquals(result.getErrorCount(), 8); BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'function test1(string aString, int " + "anInt) returns (string|error)', found 'function test1(string str, int " + "anInt)" + - " returns (string|error)'", 51, 5); + " returns (string|error)'", 53, 5); BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'public function test2(string aString)', " + - "found 'function test2(string aString)'", 56, 5); + "found 'function test2(string aString)'", 58, 5); BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'function test3(int anInt, string " + "aString, string defaultable, int def2)', found 'function test3(string " + - "aString, int anInt, string defaultable, int def2) returns string'", 59, 5); + "aString, int anInt, string defaultable, int def2) returns string'", 61, 5); BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'function test4(string aString, int " + "anInt, Bar... bars) returns string', found 'function test4(string aString," + - " int anInt, AnotherBar... bars) returns string'", 64, 5); + " int anInt, AnotherBar... bars) returns string'", 66, 5); BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'function test5(ON|OFF... status) returns" + - " Bar', found 'function test5(ON|OFF... stat) returns Bar'", 69, 5); + " Bar', found 'function test5(ON|OFF... stat) returns Bar'", 71, 5); BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'function test6([string,ON|OFF]... tup)'," + - " found 'function test6([string,ON|OFF]... tupl)'", 74, 5); - BAssertUtil.validateError(result, index, + " found 'function test6([string,ON|OFF]... tupl)'", 76, 5); + BAssertUtil.validateError(result, index++, "mismatched function signatures: expected 'function test7() returns ON|OFF', found " + - "'function test7(int x) returns ON|OFF'", 77, 5); + "'function test7(int x) returns ON|OFF'", 79, 5); + BAssertUtil.validateError(result, index, + "mismatched function signatures: expected 'function test8(public string s, int i)'," + + " found 'function test8(string s, public int i)'", 84, 5); + } + + @Test + public void testInvalidTypeReferenceAcrossModules() { + CompileResult result = BCompileUtil.compile("test-src/object/ObjectProject", "object_reference_negative"); + int index = 0; + + Assert.assertEquals(result.getErrorCount(), 3); + BAssertUtil.validateError(result, index++, + "incompatible type reference 'abc:Foo': a referenced object cannot have non-public " + + "fields or methods", 20, 6); + BAssertUtil.validateError(result, index++, + "incompatible type reference 'abc:Bar': a referenced object cannot have non-public " + + "fields or methods", 21, 6); + BAssertUtil.validateError(result, index, + "incompatible type reference 'abc:Baz': a referenced object cannot have non-public " + + "fields or methods", 22, 6); } } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_definitions.bal b/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_definitions.bal index ed3051b2c896..d3b2e563c834 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_definitions.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_definitions.bal @@ -116,10 +116,10 @@ function passSelfAsValue(Boy p) returns string { } public type Bin abstract object { - public int age = 10; - public string name = "sample name"; - public int year = 50; - public string month = "february"; + public int age; + public string name; + public int year; + public string month; public function attachFunc1(int add, string value1) returns [int, string]; @@ -210,8 +210,8 @@ public type Architect object { }; public type Country abstract object { - public int age = 10; - public string month = "february"; + public int age; + public string month; public function attachInterface(int add) returns int; }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_type_reference.bal b/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_type_reference.bal index 4eb574602dc8..f44f60128d56 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_type_reference.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/balo/test_projects/test_project/src/foo/object_type_reference.bal @@ -15,8 +15,8 @@ // under the License. public type Person1 abstract object { - public int age = 10; - public string name = "sample name"; + public int age; + public string name; public function getName(string greeting = "Hi") returns string; }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/jvm/object_negatives.bal b/tests/jballerina-unit-test/src/test/resources/test-src/jvm/object_negatives.bal index 2c38c9107a9b..1944964bf2d8 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/jvm/object_negatives.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/jvm/object_negatives.bal @@ -17,13 +17,13 @@ import testorg/subtyping; type ObjWithPvtField abstract object { - string name = ""; - private int ssn = 0; + string name; + private int ssn; }; type ObjWithPvtMethod abstract object { - string name = ""; - int ssn = 0; + string name; + int ssn; private function test(); }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/jvm/objects_subtyping.bal b/tests/jballerina-unit-test/src/test/resources/test-src/jvm/objects_subtyping.bal index 920d8ab5f41a..cec9b950b7b2 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/jvm/objects_subtyping.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/jvm/objects_subtyping.bal @@ -66,8 +66,8 @@ function testCastingRuntimeError() returns Person1 { } type AbstractPerson abstract object { - public string name = ""; - public int age = 0; + public string name; + public int age; public function toString() returns string; }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/ObjectProject/src/abstract_objects_with_non_public_symbols/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/ObjectProject/src/abstract_objects_with_non_public_symbols/main.bal new file mode 100644 index 000000000000..c0444730e7d4 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/ObjectProject/src/abstract_objects_with_non_public_symbols/main.bal @@ -0,0 +1,33 @@ +// Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +public type Foo abstract object { + int a; + + function m(); +}; + +public type Bar abstract object { + public int b; + + function n(); +}; + +public type Baz abstract object { + int c; + + public function o(); +}; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/ObjectProject/src/object_reference_negative/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/ObjectProject/src/object_reference_negative/main.bal new file mode 100644 index 000000000000..75b753f577c9 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/ObjectProject/src/object_reference_negative/main.bal @@ -0,0 +1,23 @@ +// Copyright (c) 2019 WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +// +// WSO2 Inc. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import abstract_objects_with_non_public_symbols as abc; + +type Bar object { + *abc:Foo; + *abc:Bar; + *abc:Baz; +}; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract-object-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract-object-negative.bal index 959ba5016fcf..7bef7351be39 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract-object-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract-object-negative.bal @@ -10,20 +10,20 @@ public function testInitAbstractObjectWithNew () { } type Person1 abstract object { - public int age = 0; - public string name = ""; + public int age; + public string name; - int year = 0; - string month = ""; + int year; + string month; }; // Abstract object with constructor method type Person2 abstract object { - public int age = 0; - public string name = ""; + public int age; + public string name; - int year = 50; - string month = "february"; + int year; + string month; function __init () { } @@ -42,21 +42,21 @@ type Person3 object { // Abstract object with method definition type Person4 abstract object { - public int age = 0; - public string name = ""; + public int age; + public string name; - int year = 0; - string month = ""; + int year; + string month; public function getName() returns string { - return self.name; + return "name"; } }; // Abstract object with private field type Person6 abstract object { - private int age = 0; - public string name = ""; + private int age; + public string name; private function getName() returns string; }; @@ -77,3 +77,8 @@ type Bar object { type Person7 abstract object { public function getName() returns string = external; }; + +// Abstract object with field with default value. +type Baz abstract object { + string xyz = "xyz"; +}; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract_object.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract_object.bal index 3d465df6e09a..cb89abe20755 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract_object.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/abstract_object.bal @@ -15,13 +15,13 @@ // under the License. public type Address abstract object { - public string city = ""; + public string city; public function getCity() returns string; }; public type StudentAddress object { - public string city = ""; + public string city; public function __init(string city){ self.city = city; @@ -33,7 +33,7 @@ public type StudentAddress object { }; public type Employee object { - public string city = ""; + public string city; public Address address; function __init(string city, Address address) { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-1-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-1-negative.bal index 7bd187eadf3a..33b4732e954f 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-1-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-1-negative.bal @@ -15,8 +15,8 @@ // under the License. type Person1 abstract object { - public int age = 10; - public string name = "sample name"; + public int age; + public string name; }; type Employee1 object { @@ -33,11 +33,11 @@ type Manager1 object { }; type EmployeeWithSalary abstract object { - public float salary = 0.0; + public float salary; }; type AnotherEmployeeWithSalary abstract object { - public int salary = 0; + public int salary; }; type ManagerWithTwoSalaries object { @@ -77,8 +77,8 @@ type E abstract object { // Test errors for unimplemented methods type Person2 abstract object { - public int age = 10; - public string name = "sample name"; + public int age; + public string name; // Unimplemented function at the nested referenced type. public function getName(string? title) returns string; @@ -86,7 +86,7 @@ type Person2 abstract object { type Employee2 abstract object { *Person2; - public float salary = 0.0; + public float salary; // Unimplemented function at the referenced type. public function getSalary() returns float; @@ -126,11 +126,11 @@ type ObjectWithRedeclaredFunction_2 abstract object { }; type RedecalredFieldObject_1 abstract object { - int x = 0; + int x; }; type RedecalredFieldObject_2 abstract object { - int x = 0; + int x; *RedecalredFieldObject_1; }; @@ -151,3 +151,30 @@ type Too object { self.s = s; } }; + +type ObjWithSameFunc1 abstract object { + function abc(); + function xyz(int i); +}; + +type ObjWithSameFunc2 abstract object { + function xyz(int i); + function def(string s) returns string; +}; + +type ObjWithRedeclaredFuncsViaRefs object { + *ObjWithSameFunc1; + *ObjWithSameFunc2; + + function xyz(int i) { + + } + + function abc() { + + } + + function def(string s) returns string { + return s; + } +}; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-2-negative.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-2-negative.bal index 8a170545daf4..00ec9be9f51b 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-2-negative.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference-2-negative.bal @@ -21,8 +21,8 @@ type Foo object { }; type Bar abstract object { - int x = 0; - string y = ""; + int x; + string y; }; type XXX object { diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference.bal index eae5624992cd..3004abc074cf 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-type-reference.bal @@ -15,14 +15,14 @@ // under the License. type Person1 abstract object { - public int age = 10; - public string name = "sample name"; + public int age; + public string name; public function getName() returns string; }; type Employee1 abstract object { - public float salary = 0.0; + public float salary; public function getSalary() returns float; }; @@ -102,7 +102,7 @@ type Manager3 object { }; type Employee2 abstract object { - public float salary = 0.0; + public float salary; *Person1; public function getSalary() returns float; @@ -136,15 +136,15 @@ type Manager4 object { }; type Employee3 abstract object { - public float salary = 0.0; + public float salary; *Person3; public function getBonus(float ratio, int months=12) returns float; }; type Person3 abstract object { - public int age = 10; - public string name = "sample name"; + public int age; + public string name; public function getName(string greeting = "Hi") returns string; }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-with-interface.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-with-interface.bal index fba1507634ae..a0b5dc454017 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/object-with-interface.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/object-with-interface.bal @@ -6,11 +6,11 @@ public function testObjectWithInterface () returns [int, string, int, string] { type Person abstract object { - public int age = 10; - public string name = "sample name"; + public int age; + public string name; - int year = 50; - string month = "february"; + int year; + string month; function attachFunc1(int add, string value1) returns [int, string]; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/object_func_reference_neg.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/object_func_reference_neg.bal index 982cfe9f922d..cc311c92f3ae 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/object_func_reference_neg.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/object_func_reference_neg.bal @@ -42,6 +42,8 @@ public type Foo abstract object { function test7() returns Status; + function test8(public string s, int i); + }; public type FooImpl1 object { @@ -77,4 +79,9 @@ public type FooImpl1 object { function test7(int x = 0) returns Status { return "ON"; } + + // param visibility modifier mismatch + function test8(string s, public int i) { + + } }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/object/object_initialize_interface_object.bal b/tests/jballerina-unit-test/src/test/resources/test-src/object/object_initialize_interface_object.bal index 3015d14a402d..f5435106f3a5 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/object/object_initialize_interface_object.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/object/object_initialize_interface_object.bal @@ -5,7 +5,7 @@ function test () returns int { } type Person abstract object { - public int age = 0; + public int age; function test(int a, string n) returns string; }; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/statements/arrays/arraysofarrays/arrays-of-arrays.bal b/tests/jballerina-unit-test/src/test/resources/test-src/statements/arrays/arraysofarrays/arrays-of-arrays.bal index faafcb91d940..853efc126585 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/statements/arrays/arraysofarrays/arrays-of-arrays.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/statements/arrays/arraysofarrays/arrays-of-arrays.bal @@ -206,11 +206,11 @@ function testArrayUnion() returns [boolean[][], string[][]] { } type Foo1 abstract object { - string fooId1 = ""; + string fooId1; }; type Foo2 abstract object { - string fooId2 = ""; + string fooId2; }; type Bar object {