Skip to content

Commit

Permalink
Merge pull request #15944 from lankavitharana/testFix
Browse files Browse the repository at this point in the history
Add object init invocation to value creator
  • Loading branch information
vinok88 authored Jun 28, 2019
2 parents a5babc4 + dc27bd1 commit f2e8b9f
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@
package org.ballerinalang.jvm;

import org.ballerinalang.jvm.types.BField;
import org.ballerinalang.jvm.types.BObjectType;
import org.ballerinalang.jvm.types.BRecordType;
import org.ballerinalang.jvm.types.BType;
import org.ballerinalang.jvm.types.TypeTags;
import org.ballerinalang.jvm.values.MapValue;
import org.ballerinalang.jvm.values.MapValueImpl;
import org.ballerinalang.jvm.values.ObjectValue;
Expand Down Expand Up @@ -58,31 +55,15 @@ public static MapValue<String, Object> createRecordValue(String pkgName, String
*/
public static ObjectValue createObjectValue(String pkgName, String objectTypeName, Object... fieldValues) {
ValueCreator valueCreator = ValueCreator.getValueCreator(pkgName);
ObjectValue objectValue = valueCreator.createObjectValue(objectTypeName);
int valCount = 0;
BObjectType objectType = objectValue.getType();
for (BField field : objectType.getFields().values()) {
Object value;
if (fieldValues.length >= valCount + 1) {
value = fieldValues[valCount];
} else {
BType fieldType = field.getFieldType();
if (fieldType.getTag() == TypeTags.OBJECT_TYPE_TAG) {
// This is a hack to avoid self references. This should be fixed properly.
if (objectTypeName.equals(fieldType.getName())) {
continue;
}
value = createObjectValue(fieldType.getPackage().toString(), fieldType.getName());
} else if (fieldType.getTag() == TypeTags.RECORD_TYPE_TAG) {
value = createRecordValue(fieldType.getPackage().toString(), fieldType.getName());
} else {
value = fieldType.getEmptyValue();
}
}
objectValue.set(field.name, value);
valCount++;
Object[] fields = new Object[fieldValues.length * 2];

// Adding boolean values for each arg
for (int i = 0, j = 0; i < fieldValues.length; i++) {
fields[j++] = fieldValues[i];
fields[j++] = true;
}
return objectValue;
//passing scheduler, strand and properties as null for the moment, but better to expose them via this method
return valueCreator.createObjectValue(objectTypeName, null, null, null, fields);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
package org.ballerinalang.jvm.values;

import org.ballerinalang.jvm.Scheduler;
import org.ballerinalang.jvm.Strand;
import org.ballerinalang.jvm.util.exceptions.BallerinaException;

import java.util.HashMap;
Expand Down Expand Up @@ -51,5 +53,6 @@ public static ValueCreator getValueCreator(String key) {

public abstract MapValue<String, Object> createRecordValue(String recordTypeName);

public abstract ObjectValue createObjectValue(String objectTypeName);
public abstract ObjectValue createObjectValue(String objectTypeName, Scheduler scheduler, Strand parent,
Map<String, Object> properties, Object[] args);
}
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ function generateCastToByte(jvm:MethodVisitor mv, bir:BType sourceType) {
// do nothing
} else if (sourceType is bir:BTypeAny ||
sourceType is bir:BTypeAnyData ||
sourceType is bir:BUnionType ||
sourceType is bir:BUnionType ||
sourceType is bir:BJSONType) {
mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToByte", io:sprintf("(L%s;)I", OBJECT), false);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ const string FUTURE_VALUE = "org/ballerinalang/jvm/values/FutureValue";
const string TYPEDESC_VALUE = "org/ballerinalang/jvm/values/TypedescValue";

const string OBJECT = "java/lang/Object";
const string MATH = "java/lang/Math";
const string MAP = "java/util/Map";
const string LINKED_HASH_MAP = "java/util/LinkedHashMap";
const string ARRAY_LIST = "java/util/ArrayList";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public function generateValueCreatorMethods(jvm:ClassWriter cw, bir:TypeDef?[] t
foreach var optionalTypeDef in typeDefs {
bir:TypeDef typeDef = getTypeDef(optionalTypeDef);
bir:BType bType = typeDef.typeValue;
if (bType is bir:BObjectType) {
if (bType is bir:BObjectType && !bType.isAbstract) {
objectTypeDefs[i] = typeDef;
i += 1;
}
Expand Down Expand Up @@ -184,19 +184,45 @@ function generateRecordValueCreateMethod(jvm:ClassWriter cw, bir:TypeDef?[] reco

function generateObjectValueCreateMethod(jvm:ClassWriter cw, bir:TypeDef?[] objectTypeDefs, string pkgName) {
jvm:MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "createObjectValue",
io:sprintf("(L%s;)L%s;", STRING_VALUE, OBJECT_VALUE), (), ());

io:sprintf("(L%s;L%s;L%s;L%s;[L%s;)L%s;", STRING_VALUE, SCHEDULER, STRAND, MAP, OBJECT, OBJECT_VALUE), (), ());

BalToJVMIndexMap indexMap = new;

bir:VariableDcl selfVar = { typeValue: "any",
name: { value: "self" },
kind: "ARG" };
bir:VariableDcl var1 = { typeValue: "string",
name: { value: "var1" },
kind: "ARG" };
bir:VariableDcl scheduler = { typeValue: "any",
name: { value: "scheduler" },
kind: "ARG" };
bir:VariableDcl parent = { typeValue: "any",
name: { value: "parent" },
kind: "ARG" };
bir:VariableDcl properties = { typeValue: "any",
name: { value: "properties" },
kind: "ARG" };
bir:VariableDcl args = { typeValue: "any",
name: { value: "args" },
kind: "ARG" };
_ = indexMap.getIndex(selfVar);
int var1Index = indexMap.getIndex(var1);
int schedulerIndex = indexMap.getIndex(scheduler);
int parentIndex = indexMap.getIndex(parent);
int propertiesIndex = indexMap.getIndex(properties);
int argsIndex = indexMap.getIndex(args);

mv.visitCode();

int fieldNameRegIndex = 1;
jvm:Label defaultCaseLabel = new jvm:Label();

// sort the fields before generating switch case
NodeSorter sorter = new();
sorter.sortByHash(objectTypeDefs);

jvm:Label[] labels = createLabelsforSwitch(mv, fieldNameRegIndex, objectTypeDefs, defaultCaseLabel);
jvm:Label[] targetLabels = createLabelsForEqualCheck(mv, fieldNameRegIndex, objectTypeDefs, labels,
jvm:Label[] labels = createLabelsforSwitch(mv, var1Index, objectTypeDefs, defaultCaseLabel);
jvm:Label[] targetLabels = createLabelsForEqualCheck(mv, var1Index, objectTypeDefs, labels,
defaultCaseLabel);

int i = 0;
Expand All @@ -213,12 +239,55 @@ function generateObjectValueCreateMethod(jvm:ClassWriter cw, bir:TypeDef?[] obje
mv.visitFieldInsn(GETSTATIC, typeOwnerClass, fieldName, io:sprintf("L%s;", BTYPE));
mv.visitTypeInsn(CHECKCAST, OBJECT_TYPE);
mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", io:sprintf("(L%s;)V", OBJECT_TYPE), false);

bir:VariableDcl tempVar = { typeValue: typeDef.typeValue,
name: { value: "tempVar" },
kind: "LOCAL" };
int tempVarIndex = indexMap.getIndex(tempVar);
mv.visitVarInsn(ASTORE, tempVarIndex);

mv.visitTypeInsn(NEW, STRAND);
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, schedulerIndex);
mv.visitVarInsn(ALOAD, parentIndex);
mv.visitVarInsn(ALOAD, propertiesIndex);
mv.visitMethodInsn(INVOKESPECIAL, STRAND, "<init>", io:sprintf("(L%s;L%s;L%s;)V", SCHEDULER, STRAND, MAP), false);
bir:VariableDcl strandVar = { typeValue: "any",
name: { value: "strandVar" },
kind: "LOCAL" };
int strandVarIndex = indexMap.getIndex(strandVar);
mv.visitVarInsn(ASTORE, strandVarIndex);

mv.visitVarInsn(ALOAD, tempVarIndex);
mv.visitVarInsn(ALOAD, strandVarIndex);

mv.visitLdcInsn("__init");
mv.visitVarInsn(ALOAD, argsIndex);

string methodDesc = io:sprintf("(L%s;L%s;[L%s;)L%s;", STRAND, STRING_VALUE, OBJECT, OBJECT);
mv.visitMethodInsn(INVOKEINTERFACE, OBJECT_VALUE, "call", methodDesc, true);

bir:VariableDcl tempResult = { typeValue: "any",
name: { value: "tempResult" },
kind: "LOCAL" };
int tempResultIndex = indexMap.getIndex(tempResult);
mv.visitVarInsn(ASTORE, tempResultIndex);
mv.visitVarInsn(ALOAD, tempResultIndex);
mv.visitTypeInsn(INSTANCEOF, ERROR_VALUE);
jvm:Label noErrorLabel = new jvm:Label();
mv.visitJumpInsn(IFEQ, noErrorLabel);
mv.visitVarInsn(ALOAD, tempResultIndex);
mv.visitTypeInsn(CHECKCAST, ERROR_VALUE);
mv.visitInsn(ATHROW);
mv.visitLabel(noErrorLabel);
mv.visitVarInsn(ALOAD, tempVarIndex);
mv.visitInsn(ARETURN);

i += 1;
}

createDefaultCase(mv, defaultCaseLabel, fieldNameRegIndex);
mv.visitMaxs(objectTypeDefs.length() + 10, objectTypeDefs.length() + 10);
createDefaultCase(mv, defaultCaseLabel, var1Index);
mv.visitMaxs(objectTypeDefs.length() + 100, objectTypeDefs.length() + 100);
mv.visitEnd();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ public static HttpResource findResource(HTTPServicesRegistry servicesRegistry, H
public static Object[] getSignatureParameters(HttpResource httpResource, HttpCarbonMessage httpCarbonMessage,
MapValue endpointConfig) {
//TODO Think of keeping struct type globally rather than creating for each request
ObjectValue listenerEndpoint = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, HTTP_LISTENER_ENDPOINT);
ObjectValue listenerEndpoint = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, HTTP_LISTENER_ENDPOINT,
9090, endpointConfig); // sending a dummy port here as it gets initialized later - fix
ObjectValue httpCaller = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, CALLER);
ObjectValue inRequest = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_HTTP, REQUEST);
ObjectValue inRequestEntity = BallerinaValues.createObjectValue(PROTOCOL_PACKAGE_MIME, ENTITY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public static Object getParentDirectory(Strand strand, ObjectValue self) {
Path parent = path.getParent();
if (parent != null) {
ObjectValue pathObject = BallerinaValues.createObjectValue(Constants.PACKAGE_PATH,
Constants.PATH_STRUCT);
Constants.PATH_STRUCT, "");
pathObject.call(strand, Constants.INIT_FUNCTION_NAME, parent.toString(), true);
return pathObject;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public static Object list(Strand strand, ObjectValue self) {
try {
Files.list(path).forEach(p -> {
ObjectValue pathObj = BallerinaValues.createObjectValue(Constants.PACKAGE_PATH,
Constants.PATH_STRUCT);
Constants.PATH_STRUCT, "");
pathObj.call(strand, Constants.INIT_FUNCTION_NAME, p.toString(), true);
long index = filesList.size();
filesList.add((index), pathObj);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static ObjectValue resolve(Strand strand, ObjectValue self, ArrayValue pa
}

ObjectValue parentPathStruct = BallerinaValues.createObjectValue(Constants.PACKAGE_PATH, Constants
.PATH_STRUCT);
.PATH_STRUCT, "");
parentPathStruct.call(strand, Constants.INIT_FUNCTION_NAME, newPath.toString(), true);
return parentPathStruct;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.ballerinalang.connector.api.BLangConnectorSPIUtil;
import org.ballerinalang.jvm.BallerinaValues;
import org.ballerinalang.jvm.Strand;
import org.ballerinalang.jvm.values.MapValue;
import org.ballerinalang.jvm.values.ObjectValue;
import org.ballerinalang.model.types.TypeKind;
import org.ballerinalang.model.values.BMap;
Expand Down Expand Up @@ -77,11 +76,11 @@ public void execute(Context context) {
context.setReturnValues(absolutePath);
}

public static MapValue toAbsolutePath(Strand strand, ObjectValue self) {
public static ObjectValue toAbsolutePath(Strand strand, ObjectValue self) {
Path path = (Path) self.getNativeData(Constants.PATH_DEFINITION_NAME);
MapValue<String, Object> absolutePath =
BallerinaValues.createRecord(BallerinaValues.createRecordValue(Constants.PACKAGE_PATH,
Constants.PATH_STRUCT), getAbsolutePath(path).toString());
ObjectValue absolutePath =
BallerinaValues.createObjectValue(Constants.PACKAGE_PATH,
Constants.PATH_STRUCT, getAbsolutePath(path).toString());
return absolutePath;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ public void testPrivateFieldAccess() {
BAssertUtil.validateError(compileResult, index++, "undefined symbol 'methodInt3'", 17, 49);
BAssertUtil.validateError(compileResult, index++, "cannot assign a value to function argument 'a'", 29, 9);
BAssertUtil.validateError(compileResult, index++, "cannot assign a value to function argument 'fOut'", 34, 17);
BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 50, 9);
BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 50, 13);
BAssertUtil.validateError(compileResult, index++, "cannot assign a value to function argument 'a'", 56, 13);
BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 64, 17);
BAssertUtil.validateError(compileResult, index++, "redeclared symbol 'a'", 64, 21);
BAssertUtil.validateError(compileResult, index++, "undefined symbol 'l'", 81, 58);
BAssertUtil.validateError(compileResult, index++, "undefined symbol 'm'", 81, 62);
BAssertUtil.validateError(compileResult, index++, "undefined symbol 'n'", 81, 66);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ function test15() returns int {
return foo.call(7);
}

function testClosureWithTupleTypes((string, float, string) g) returns (function (string, (string, float, string)) returns (string)){
return function (string x, (string, float, string) y) returns (string) {
var (i, j, k) = y;
var (l, m, n) = g;
function testClosureWithTupleTypes([string, float, string] g) returns (function (string, [string, float, string]) returns (string)){
return function (string x, [string, float, string] y) returns (string) {
var [i, j, k] = y;
var [l, m, n] = g;
return x + i + j + k + l + m + n;
};
}
Expand All @@ -248,23 +248,23 @@ function test16() returns string {
string a = "Hello";
float b = 11.1;
string c = "World !!!";
var foo = testClosureWithTupleTypes((a, b, c));
var foo = testClosureWithTupleTypes([a, b, c]);
string i = "Ballerina";
float j = 15.0;
string k = "Program !!!";
return foo.call("Im", (i, j, k));
return foo.call("Im", [i, j, k]);
}

function testClosureWithTupleTypesOrder((string, float, string) g) returns (function ((string, float, string), string) returns (string)){
function testClosureWithTupleTypesOrder([string, float, string] g) returns (function ([string, float, string], string) returns (string)){
string i = "HelloInner";
float j = 44.8;
string k = "World Inner!!!";
(string, float, string) r = (i, j, k);
[string, float, string] r = [i, j, k];

return function ((string, float, string) y, string x) returns (string) {
var (a, b, c) = g;
var (d, e, f) = y;
var (i1, j1, k1) = r;
return function ([string, float, string] y, string x) returns (string) {
var [a, b, c] = g;
var [d, e, f] = y;
var [i1, j1, k1] = r;

return x + a + b + c + d + e + f + i1 + j1 + k1;
};
Expand All @@ -279,8 +279,8 @@ function test17() returns string {
float b = 11.1;
string c = "World !!!";

var foo = testClosureWithTupleTypesOrder((a, b, c));
return foo.call((d, e, f), "I'm");
var foo = testClosureWithTupleTypesOrder([a, b, c]);
return foo.call([d, e, f], "I'm");
}

function globalVarAccessAndModifyTest() returns (int) {
Expand Down Expand Up @@ -592,14 +592,14 @@ function testMultiLevelBlockStatements2() returns (function(int[], int[], int[])
}


function test28() returns (int, int) {
function test28() returns [int, int] {
var foo = testMultiLevelBlockStatements1();
var baz = foo.call();
var bar = testMultiLevelBlockStatements2();
int[] i = [1,2];
int[] j = [1,2,3];
int[] k = [1,2,3,4];
return (baz.call(4), bar.call(i,j,k));
return [baz.call(4), bar.call(i,j,k)];
}


Expand Down Expand Up @@ -629,7 +629,7 @@ function function4(string firstParameter) returns (function (string) returns boo
};
}

function test29() returns (boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean) {
function test29() returns [boolean, boolean, boolean, boolean, boolean, boolean, boolean, boolean] {
var a1 = function1("ABC");
boolean b10 = a1.call("ABC");
boolean b11 = a1.call("GHJ");
Expand All @@ -646,7 +646,7 @@ function test29() returns (boolean, boolean, boolean, boolean, boolean, boolean,
boolean b40 = a4.call("ABC");
boolean b41 = a4.call("ERWWS");

return (b10, b11, b20, b21, b30, b31, b40, b41);
return [b10, b11, b20, b21, b30, b31, b40, b41];
}

function test30() returns int|string {
Expand Down
3 changes: 2 additions & 1 deletion tests/jballerina-unit-test/src/test/resources/testng.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<package name="org.ballerinalang.test.annotations.*"/>
<package name="org.ballerinalang.test.imports.*"/>
<package name="org.ballerinalang.test.parser.*"/>
<package name="org.ballerinalang.test.closures.*"/>
<!-- <package name="org.ballerinalang.test.privacy.*"/> -->
<package name="org.ballerinalang.test.dataflow.*"/>
<package name="org.ballerinalang.test.variable.shadowing.*"/>
Expand Down Expand Up @@ -93,6 +94,7 @@
<package name="org.ballerinalang.test.expressions.ternary.*"/>
<package name="org.ballerinalang.test.expressions.typeof.*"/>
<package name="org.ballerinalang.test.expressions.stamp.*"/>
<package name="org.ballerinalang.test.expressions.invocations.*"/>
<package name="org.ballerinalang.test.object.*" />
<package name="org.ballerinalang.test.dataflow.analysis.*" />
<package name="org.ballerinalang.test.documentation.*" />
Expand All @@ -117,7 +119,6 @@
</methods>
</class>
<class name="org.ballerinalang.test.functions.FunctionsWithDefaultableArguments" />
<class name="org.ballerinalang.test.closures.VarMutabilityClosureTest" />
<class name="org.ballerinalang.test.worker.WorkerCallingFunction"/>
<class name="org.ballerinalang.test.worker.BasicForkTest"/>
<class name="org.ballerinalang.test.worker.BasicWorkerTest"/>
Expand Down

0 comments on commit f2e8b9f

Please sign in to comment.