Skip to content

Commit

Permalink
Merge pull request #42737 from nipunayf/fix-42725
Browse files Browse the repository at this point in the history
Implement the `getLocation` API for structured type symbols
  • Loading branch information
nipunayf committed May 17, 2024
2 parents b579c8a + e3fe019 commit 5ddcc9f
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com)
*
* WSO2 LLC. 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.
*/

package io.ballerina.compiler.api.impl.symbols;

import io.ballerina.compiler.api.symbols.TypeDescKind;
import io.ballerina.tools.diagnostics.Location;
import org.wso2.ballerinalang.compiler.semantics.model.types.BType;
import org.wso2.ballerinalang.compiler.util.CompilerContext;

import java.util.Optional;

/**
* Represents a Ballerina structured type descriptor.
*
* @since 2201.10.0
*/
public abstract class AbstractStructuredTypeSymbol extends AbstractTypeSymbol {

public AbstractStructuredTypeSymbol(CompilerContext context,
TypeDescKind typeDescKind,
BType bType) {
super(context, typeDescKind, bType);
}

@Override
public Optional<Location> getLocation() {
return Optional.of(this.getBType().tsymbol.pos);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
*
* @since 2.0.0
*/
public class BallerinaArrayTypeSymbol extends AbstractTypeSymbol implements ArrayTypeSymbol {
public class BallerinaArrayTypeSymbol extends AbstractStructuredTypeSymbol implements ArrayTypeSymbol {
private Integer size;
private TypeSymbol memberTypeDesc;
private String signature;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
*
* @since 2.0.0
*/
public class BallerinaMapTypeSymbol extends AbstractTypeSymbol implements MapTypeSymbol {
public class BallerinaMapTypeSymbol extends AbstractStructuredTypeSymbol implements MapTypeSymbol {

private TypeSymbol memberTypeDesc;
private String signature;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*
* @since 2.0.0
*/
public class BallerinaRecordTypeSymbol extends AbstractTypeSymbol implements RecordTypeSymbol {
public class BallerinaRecordTypeSymbol extends AbstractStructuredTypeSymbol implements RecordTypeSymbol {

private Map<String, RecordFieldSymbol> fieldSymbols;
private TypeSymbol restTypeDesc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
*
* @since 2.0.0
*/
public class BallerinaTableTypeSymbol extends AbstractTypeSymbol implements TableTypeSymbol {
public class BallerinaTableTypeSymbol extends AbstractStructuredTypeSymbol implements TableTypeSymbol {

private static final String ORG_NAME_BALLERINA = "ballerina";
private static final String MODULE_NAME_LANG_TABLE = "lang.table";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
*
* @since 2.0.0
*/
public class BallerinaTupleTypeSymbol extends AbstractTypeSymbol implements TupleTypeSymbol {
public class BallerinaTupleTypeSymbol extends AbstractStructuredTypeSymbol implements TupleTypeSymbol {

private List<TypeSymbol> memberTypes;
private List<MemberTypeSymbol> tupleMembers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import io.ballerina.compiler.api.symbols.TypeSymbol;
import io.ballerina.projects.Document;
import io.ballerina.projects.Project;
import io.ballerina.tools.diagnostics.Location;
import io.ballerina.tools.text.LinePosition;
import io.ballerina.tools.text.LineRange;
import org.ballerinalang.test.BCompileUtil;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
Expand Down Expand Up @@ -97,11 +99,8 @@ public Object[][] getTypePosition() {
// {26, 4, TypeDescKind.XML, "xml"},
// {27, 4, TypeDescKind.XML, "xml<xml>"},
// {28, 4, TypeDescKind.XML, "xml<ballerina/lang.xml:0.8.0:Element>"},
{30, 4, MAP, "map<string>"},
{31, 4, TYPEDESC, "typedesc<anydata>"},
{32, 4, TYPEDESC, "typedesc<any|error>"},
{33, 4, TABLE, "table<Person>"},
{34, 4, TABLE, "table<Person> key<int>"},
{35, 4, FUTURE, "future<string>"},
{36, 4, FUTURE, "future<any|error>"},
{40, 4, INT, "int"},
Expand All @@ -123,6 +122,25 @@ public Object[][] getTypePosition() {
};
}

@Test(dataProvider = "StructuredPosProvider")
public void testStructuredTypeSymbolLookup(int line, int sCol, int eCol, TypeDescKind typeKind, String signature) {
TypeSymbol type = assertBasicsAndGetType(line, sCol, typeKind, signature);
assertTrue(type.getName().isEmpty());

Optional<Location> location = type.getLocation();
assertTrue(location.isPresent());
assertLocationPosition(location.get().lineRange(), line, sCol, eCol);
}

@DataProvider(name = "StructuredPosProvider")
public Object[][] getStructuredTypePosition() {
return new Object[][]{
{30, 4, 15, MAP, "map<string>"},
{33, 4, 17, TABLE, "table<Person>"},
{34, 4, 26, TABLE, "table<Person> key<int>"}
};
}

@Test(dataProvider = "ConstrainedTypePosProvider")
public void testConstrainedTypes(int line, int col, TypeDescKind typeKind, String signature) {
assertBasicsAndGetType(line, col, typeKind, signature);
Expand Down Expand Up @@ -203,6 +221,29 @@ public Object[][] getTupleTypePosition() {
};
}

@Test(dataProvider = "StructuredTypeSymbolLocationPos")
public void testStructuredTypeSymbolLocation(int line, int col, int expLine, int expSCol, int expECol) {
Optional<TypeSymbol> typeSymbol = model.typeOf(
LineRange.from(srcFile.name(), LinePosition.from(line, 8), LinePosition.from(line, col)));
assertTrue(typeSymbol.isPresent());

Optional<Location> location = typeSymbol.get().getLocation();
assertTrue(location.isPresent());
assertLocationPosition(location.get().lineRange(), expLine, expSCol, expECol);
}

@DataProvider(name = "StructuredTypeSymbolLocationPos")
public Object[][] getStructuredTypeSymbolLocationPos() {
return new Object[][]{
{67, 11, 90, 0, 5},
{68, 10, 91, 0, 11},
{69, 13, 92, 0, 13},
{70, 11, 93, 0, 30},
{71, 11, 94, 5, 8},
{72, 11, 96, 0, 10},
};
}

// private utils
private TypeSymbol assertBasicsAndGetType(int line, int col, TypeDescKind typeKind, String signature) {
Optional<Symbol> symbol = model.symbol(srcFile, LinePosition.from(line, col));
Expand All @@ -215,4 +256,13 @@ private TypeSymbol assertBasicsAndGetType(int line, int col, TypeDescKind typeKi
assertEquals(type.signature(), signature);
return (TypeSymbol) symbol.get();
}

private void assertLocationPosition(LineRange actualLineRange, int line, int sCol, int eCol) {
LinePosition startLine = actualLineRange.startLine();
LinePosition endLine = actualLineRange.endLine();
assertEquals(startLine.line(), line);
assertEquals(endLine.line(), line);
assertEquals(startLine.offset(), sCol);
assertEquals(endLine.offset(), eCol);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ function otherTypes() {
distinct error err;
}

function fn() {
_ = arr;
_ = mp;
_ = tuple;
_ = rec;
_ = row;
_ = tbl;
}

// utils
const FOO = "foo";
const TEN = 10;
Expand All @@ -78,3 +87,11 @@ type ErrorData record {|
string message;
error cause?;
|};

int[] arr = [];
map<string> mp = {};
[int, string] tuple = [1, "a"];
record {|string id; int val;|} rec = {val: 0, id: ""};
type Row record {|int id; boolean flag;|};
Row row = {id: 0, flag: false};
table<Row> tbl = table [];

0 comments on commit 5ddcc9f

Please sign in to comment.