Skip to content

Commit

Permalink
feat: Add a name property to AssociativeArrayDatatype and RecordDatatype
Browse files Browse the repository at this point in the history
  • Loading branch information
felipebz committed Aug 29, 2023
1 parent f424ffd commit c160256
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,23 @@ class SymbolVisitor(private val typeSolver: DefaultTypeSolver, private val globa

private fun visitAssociativeArrayDeclaration(node: AstNode) {
val identifier = node.getFirstChild(PlSqlGrammar.IDENTIFIER_NAME)
createSymbol(identifier, Symbol.Kind.TYPE, AssociativeArrayDatatype(node))
val datatype = node.getFirstChild(PlSqlGrammar.NESTED_TABLE_DEFINITION).getFirstChild(PlSqlGrammar.DATATYPE)
createSymbol(identifier, Symbol.Kind.TYPE, AssociativeArrayDatatype(node, currentScope, solveType(datatype)))
}

private fun visitRecordDeclaration(node: AstNode) {
val identifier = node.getFirstChild(PlSqlGrammar.IDENTIFIER_NAME)
createSymbol(identifier, Symbol.Kind.TYPE, RecordDatatype())

val scope = currentScope ?: throw IllegalStateException("Cannot create a symbol without a scope.")

val fields = node.getChildren(PlSqlGrammar.RECORD_FIELD_DECLARATION).map { field ->
val fieldName = field.getFirstChild(PlSqlGrammar.IDENTIFIER_NAME)
val datatype = field.getFirstChild(PlSqlGrammar.DATATYPE)
val type = solveType(datatype)
Symbol(fieldName, Symbol.Kind.VARIABLE, scope, type)
}

createSymbol(identifier, Symbol.Kind.TYPE, RecordDatatype(node, currentScope, fields))
}

private fun visitParameterDeclaration(node: AstNode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ package org.sonar.plugins.plsqlopen.api.symbols.datatype
import com.felipebz.flr.api.AstNode
import org.sonar.plugins.plsqlopen.api.PlSqlGrammar
import org.sonar.plugins.plsqlopen.api.symbols.PlSqlType
import org.sonar.plugins.plsqlopen.api.symbols.Scope

class AssociativeArrayDatatype(node: AstNode? = null) : PlSqlDatatype {
class AssociativeArrayDatatype(node: AstNode? = null, currentScope: Scope?, val nestedType: PlSqlDatatype) : PlSqlDatatype {
override val type = PlSqlType.ASSOCIATIVE_ARRAY

val nestedType = node?.getFirstChild(PlSqlGrammar.NESTED_TABLE_DEFINITION)?.getFirstChild(PlSqlGrammar.DATATYPE)?.tokenOriginalValue
?: throw IllegalStateException("Associative array must have a nested type")
val name: String = currentScope?.let {
if (it.identifier != null && it.type == PlSqlGrammar.CREATE_PACKAGE)
it.identifier + "."
else "" } +
node?.getFirstChild(PlSqlGrammar.IDENTIFIER_NAME)?.tokenOriginalValue

override fun toString(): String {
return "AssociativeArray{nestedType=$nestedType}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,21 @@
*/
package org.sonar.plugins.plsqlopen.api.symbols.datatype

import com.felipebz.flr.api.AstNode
import org.sonar.plugins.plsqlopen.api.PlSqlGrammar
import org.sonar.plugins.plsqlopen.api.symbols.PlSqlType
import org.sonar.plugins.plsqlopen.api.symbols.Scope
import org.sonar.plugins.plsqlopen.api.symbols.Symbol

class RecordDatatype : PlSqlDatatype {
class RecordDatatype(node: AstNode? = null, currentScope: Scope?, val fields: List<Symbol>) : PlSqlDatatype {
override val type = PlSqlType.RECORD

val name: String = currentScope?.let {
if (it.identifier != null && it.type == PlSqlGrammar.CREATE_PACKAGE)
it.identifier + "."
else "" } +
node?.getFirstChild(PlSqlGrammar.IDENTIFIER_NAME)?.tokenOriginalValue

override fun toString(): String {
return "Record"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import org.sonar.plsqlopen.TestPlSqlVisitorRunner
import org.sonar.plugins.plsqlopen.api.symbols.PlSqlType
import org.sonar.plugins.plsqlopen.api.symbols.Symbol
import org.sonar.plugins.plsqlopen.api.symbols.datatype.NumericDatatype
import org.sonar.plugins.plsqlopen.api.symbols.datatype.RecordDatatype
import java.io.File

class SymbolVisitorTest {
Expand Down Expand Up @@ -116,11 +117,50 @@ end;
assertThat(type.type).isEqualTo(PlSqlType.RECORD)
assertThat(type.innerScope).isNull()

val datatype = type.datatype as RecordDatatype
assertThat(datatype.name).isEqualTo("my_record");

val variable = symbols.find("variable", 3, 3)
assertThat(variable.type).isEqualTo(PlSqlType.RECORD)
assertThat(variable.references).isEmpty()
}

@Test
fun recordInProcedure() {
val symbols = scan("""
create or replace procedure my_proc is
type my_record is record (x number);
begin
null;
end;
""")
assertThat(symbols).hasSize(2) // TODO

val type = symbols.find("my_record", 2, 8)
assertThat(type.type).isEqualTo(PlSqlType.RECORD)
assertThat(type.innerScope).isNull()

val datatype = type.datatype as RecordDatatype
assertThat(datatype.name).isEqualTo("my_record");
}

@Test
fun recordInPackage() {
val symbols = scan("""
create or replace package my_pack is
type my_record is record (x number);
end;
""")
assertThat(symbols).hasSize(2) // TODO

val type = symbols.find("my_record", 2, 8)
assertThat(type.type).isEqualTo(PlSqlType.RECORD)
assertThat(type.innerScope).isNull()

val datatype = type.datatype as RecordDatatype
assertThat(datatype.name).isEqualTo("my_pack.my_record");
}

@Test
fun forLoop() {
val symbols = scan("""
Expand Down

0 comments on commit c160256

Please sign in to comment.