Skip to content

Commit

Permalink
Introduce compiler api to get generic type of a Lambda (#3300)
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelbey authored Dec 12, 2024
1 parent feae92b commit 45aa095
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package org.finos.legend.engine.language.pure.compiler;

import java.io.IOException;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.CompileContext;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperModelBuilder;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.HelperValueSpecificationBuilder;
Expand All @@ -22,13 +23,18 @@
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModelProcessParameter;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.RelationTypeHelper;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.type.GenericType;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.finos.legend.engine.shared.core.deployment.DeploymentMode;
import org.finos.legend.engine.shared.core.operational.Assert;
import org.finos.legend.pure.generated.Root_meta_protocols_pure_vX_X_X_metamodel_type_GenericType;
import org.finos.legend.pure.generated.core_pure_protocol_protocol;
import org.finos.legend.pure.generated.core_pure_protocol_vX_X_X_transfers_metamodel;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.RelationType;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.valuespecification.ValueSpecification;
import org.finos.legend.pure.runtime.java.compiled.metadata.Metadata;
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type;

public class Compiler
{
Expand Down Expand Up @@ -76,4 +82,19 @@ public static String getLambdaReturnType(Lambda lambda, PureModel pureModel)
ValueSpecification valueSpecification = getLambdaRawType(lambda, pureModel);
return HelperModelBuilder.getTypeFullPath(valueSpecification._genericType()._rawType(), pureModel.getExecutionSupport());
}

public static GenericType getLambdaReturnGenericType(Lambda lambda, PureModel pureModel)
{
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType genericType = getLambdaRawType(lambda, pureModel)._genericType();
Root_meta_protocols_pure_vX_X_X_metamodel_type_GenericType protocolGenericType = core_pure_protocol_vX_X_X_transfers_metamodel.Root_meta_protocols_pure_vX_X_X_transformation_fromPureGraph_domain_transformGenericType_GenericType_1__GenericType_1_(genericType, pureModel.getExecutionSupport());
String json = core_pure_protocol_protocol.Root_meta_alloy_metadataServer_alloyToJSON_Any_1__String_1_(protocolGenericType, pureModel.getExecutionSupport());
try
{
return ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports().readValue(json, GenericType.class);
}
catch (IOException e)
{
throw new UnsupportedOperationException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2024 Goldman Sachs
//
// Licensed 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 org.finos.legend.engine.language.pure.compiler;

import java.util.stream.Collectors;
import org.eclipse.collections.api.factory.Lists;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser;
import org.finos.legend.engine.protocol.pure.v1.model.type.GenericType;
import org.finos.legend.engine.protocol.pure.v1.model.type.PackageableType;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.junit.Assert;
import org.junit.Test;

public class CompilerTest
{
@Test
public void getLambdaReturnGenericTypeForPrimitive()
{
Lambda lambda = PureGrammarParser.newInstance().parseLambda("|1234");
GenericType genericType = Compiler.getLambdaReturnGenericType(lambda, PureModel.getCorePureModel());
Assert.assertTrue(genericType.rawType instanceof PackageableType);
Assert.assertEquals("Integer", ((PackageableType) genericType.rawType).fullPath);
}

@Test
public void getLambdaReturnGenericTypeWithTypeArguments()
{
Lambda lambda = PureGrammarParser.newInstance().parseLambda("|pair(1, '2')");
GenericType genericType = Compiler.getLambdaReturnGenericType(lambda, PureModel.getCorePureModel());
Assert.assertTrue(genericType.rawType instanceof PackageableType);
Assert.assertEquals("meta::pure::functions::collection::Pair", ((PackageableType) genericType.rawType).fullPath);
Assert.assertEquals(Lists.mutable.with("Integer", "String"), genericType.typeArguments.stream().map(x -> ((PackageableType) x.rawType).fullPath).collect(Collectors.toList()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,17 @@ Class meta::protocols::pure::vX_X_X::metamodel::type::PackageableType extends me

}

Class meta::protocols::pure::vX_X_X::metamodel::type::RelationType extends meta::protocols::pure::vX_X_X::metamodel::type::Type
{
columns: meta::protocols::pure::vX_X_X::metamodel::type::Column[*];
}

Class meta::protocols::pure::vX_X_X::metamodel::type::Column
{
name: String[1];
type: String[1];
}

Class meta::protocols::pure::vX_X_X::metamodel::type::GenericType
{
rawType : meta::protocols::pure::vX_X_X::metamodel::type::Type[1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,16 +140,31 @@ function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::domain::t

function meta::protocols::pure::vX_X_X::transformation::fromPureGraph::domain::transformGenericType(genericType:GenericType[1]):meta::protocols::pure::vX_X_X::metamodel::type::GenericType[1]
{
^meta::protocols::pure::vX_X_X::metamodel::type::GenericType
(
rawType = ^meta::protocols::pure::vX_X_X::metamodel::type::PackageableType
(
_type='packageableType',
fullPath=$genericType.rawType->toOne()->elementToPath()
),
typeArguments = $genericType.typeArguments->map(ta|$ta->transformGenericType()),
multiplicityArguments = $genericType.multiplicityArguments->map(ma|$ma->meta::protocols::pure::vX_X_X::transformation::fromPureGraph::domain::transformMultiplicity())
)
let rawType = $genericType.rawType->match([
rel: meta::pure::metamodel::relation::RelationType<Any>[1] | ^meta::protocols::pure::vX_X_X::metamodel::type::RelationType
(
_type='relationType',
columns=$rel.columns->map(c |
^meta::protocols::pure::vX_X_X::metamodel::type::Column
(
name = $c.name->toOne(),
type = $c.classifierGenericType.typeArguments->at(1).rawType->toOne()->elementToPath()
)
)
),
type: Type[1] | ^meta::protocols::pure::vX_X_X::metamodel::type::PackageableType
(
_type='packageableType',
fullPath=$genericType.rawType->toOne()->elementToPath()
)
]);

^meta::protocols::pure::vX_X_X::metamodel::type::GenericType
(
rawType = $rawType,
typeArguments = $genericType.typeArguments->map(ta|$ta->transformGenericType()),
multiplicityArguments = $genericType.multiplicityArguments->map(ma|$ma->meta::protocols::pure::vX_X_X::transformation::fromPureGraph::domain::transformMultiplicity())
);
}

function <<access.private>> meta::protocols::pure::vX_X_X::transformation::fromPureGraph::domain::transformProperty(property:Property<Nil,Any|*>[1], extensions:meta::pure::extension::Extension[*]):meta::protocols::pure::vX_X_X::metamodel::domain::Property[1]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@
<artifactId>legend-engine-pure-runtime-java-extension-compiled-functions-json</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.javacrumbs.json-unit</groupId>
<artifactId>json-unit</artifactId>
<scope>test</scope>
</dependency>
<!-- TEST - For TC build only - Remove for OSS - investigate why we need this dependency -->
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@

package org.finos.legend.engine.language.pure.compiler.test;

import net.javacrumbs.jsonunit.JsonAssert;
import org.eclipse.collections.api.tuple.Pair;
import org.finos.legend.engine.language.pure.compiler.Compiler;
import org.finos.legend.engine.language.pure.compiler.toPureGraph.PureModel;
import org.finos.legend.engine.language.pure.grammar.from.PureGrammarParser;
import org.finos.legend.engine.protocol.pure.v1.model.context.PureModelContextData;
import org.finos.legend.engine.protocol.pure.v1.model.type.GenericType;
import org.finos.legend.engine.protocol.pure.v1.model.valueSpecification.raw.Lambda;
import org.finos.legend.engine.shared.core.ObjectMapperFactory;
import org.junit.Test;

public class TestRelationFunctions extends TestCompilationFromGrammar.TestCompilationFromGrammarTestSuite
Expand All @@ -33,6 +42,22 @@ public void testFilter()
);
}

@Test
public void lambdaRelationReturnType() throws Exception
{
Pair<PureModelContextData, PureModel> pureModelPair = test(
"###Relational\n" +
"Database a::A (Table tb(id Integer))\n"
);

Lambda lambda = PureGrammarParser.newInstance().parseLambda("|#>{a::A.tb}#->select()");
GenericType genericType = Compiler.getLambdaReturnGenericType(lambda, pureModelPair.getTwo());
String actualValue = ObjectMapperFactory.getNewStandardObjectMapperWithPureProtocolExtensionSupports().writeValueAsString(genericType);
JsonAssert.assertJsonEquals(
"{\"multiplicityArguments\":[],\"rawType\":{\"_type\":\"packageableType\",\"fullPath\":\"meta::pure::store::RelationStoreAccessor\"},\"typeArguments\":[{\"multiplicityArguments\":[],\"rawType\":{\"_type\":\"relationType\",\"columns\":[{\"name\":\"id\",\"type\":\"Integer\"}]},\"typeArguments\":[],\"typeVariableValues\":[]}],\"typeVariableValues\":[]}",
actualValue);
}

@Test
public void testFilterError()
{
Expand Down

0 comments on commit 45aa095

Please sign in to comment.