Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

review: feature: introduce the concept of "Pattern" #1686

Merged
merged 140 commits into from
Jun 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
140 commits
Select commit Hold shift + click to select a range
34c3b2e
feat: Metamodel provides metadata about Spoon types and fields
pvojtechovsky Mar 3, 2018
274efac
rename MMType, MMField - runtime metamodel
pvojtechovsky Mar 7, 2018
5c4f605
Pattern
pvojtechovsky Mar 7, 2018
40d9f01
rename MMType, MMField - pattern
pvojtechovsky Mar 7, 2018
25b3fc1
Factory is available during whole generation process
pvojtechovsky Mar 7, 2018
967f405
move parameter classes to own package
pvojtechovsky Mar 7, 2018
5806741
rename Accessor to ParameterInfo
pvojtechovsky Mar 7, 2018
8fc3ed5
Rename Parameters
pvojtechovsky Mar 7, 2018
f9a5060
All Node classes moved to package node
pvojtechovsky Mar 7, 2018
5ce66bb
Generator used in generation process
pvojtechovsky Mar 7, 2018
964bf84
rename Node to RootNode (to avoid Eclipse problem with `Node`)
pvojtechovsky Mar 7, 2018
7414078
AbstractNode#toString
pvojtechovsky Mar 7, 2018
e71c085
Printing of pattern sources of live statements
pvojtechovsky Mar 7, 2018
c54079b
ElementNode toString
pvojtechovsky Mar 7, 2018
0fd2162
matcher ignores some roles
pvojtechovsky Mar 7, 2018
94881ea
fix Template containerKind
pvojtechovsky Mar 7, 2018
ed3286c
position is generated too - same like before
pvojtechovsky Mar 7, 2018
89970cc
generate by
pvojtechovsky Mar 7, 2018
cdf3685
support of generated by comments
pvojtechovsky Mar 8, 2018
34a0cfd
simplify generated code
pvojtechovsky Mar 8, 2018
4cf1675
Pattern printing
pvojtechovsky Mar 8, 2018
18e7800
Support specific matcher + generic matcher for other container items
pvojtechovsky Mar 9, 2018
03afb4c
Matching of MapEntries
pvojtechovsky Mar 10, 2018
287d60f
fix tests and some docu
pvojtechovsky Mar 10, 2018
6d2312d
more comments
pvojtechovsky Mar 10, 2018
712ebc4
fix runtime metamodel
pvojtechovsky Mar 13, 2018
89935b8
fix runtime metamodel test
pvojtechovsky Mar 13, 2018
9b26a20
checkstyle and fixed some java doc
pvojtechovsky Mar 14, 2018
98d18b8
review testTemplateMatchOfMultipleElements
monperrus Mar 16, 2018
3b3ca5e
Pattern can be created from spoon AST directly
pvojtechovsky Mar 17, 2018
fc7050a
added explanation of PatternBuilder selector
pvojtechovsky Mar 17, 2018
bb50912
some javadoc added to TemplateModelBuilder
pvojtechovsky Mar 17, 2018
eb84831
up
monperrus Mar 17, 2018
7c35eb3
javadoc of Match
pvojtechovsky Mar 17, 2018
32402ae
check style
pvojtechovsky Mar 17, 2018
4dca389
up
monperrus Mar 17, 2018
26c8cb0
added comment
pvojtechovsky Mar 17, 2018
3fa34b3
remove default implementation to force children define behavior
pvojtechovsky Mar 18, 2018
9d1f9c4
cleaning and test of matching in Set
pvojtechovsky Mar 18, 2018
2e392db
Documentation updated - 1st part ... TODO
pvojtechovsky Mar 20, 2018
39c2d56
PatternBuilder documentation
pvojtechovsky Mar 20, 2018
f805d64
rename `live` to `inline` statements
pvojtechovsky Mar 21, 2018
bf53692
fix template_definition documentation
pvojtechovsky Mar 21, 2018
60e0ebd
TemplateModelBuilder moved to separate file
pvojtechovsky Mar 21, 2018
26b1f26
fix docu
pvojtechovsky Mar 21, 2018
9f8b8bf
work on API and tests
monperrus Mar 21, 2018
a692251
up
monperrus Mar 23, 2018
cdf1a57
up
monperrus Mar 23, 2018
9ae435b
check all params of both matches
pvojtechovsky Mar 24, 2018
f257c12
patternModel is unmodifiable list. method selectNodes was deleted
pvojtechovsky Mar 24, 2018
0b19d6b
fix tests
pvojtechovsky Mar 24, 2018
9dcffea
check if declaring type is computable
pvojtechovsky Mar 24, 2018
a3e3927
remove declaring typeRef from PatternBuilder#create
pvojtechovsky Mar 24, 2018
f675ade
configureLocalParameters is package protected
pvojtechovsky Mar 24, 2018
8fdb2a2
test of generating of self referenced methods and types
pvojtechovsky Mar 24, 2018
9e7f91a
hiding some methods, tests
pvojtechovsky Mar 24, 2018
983b129
up
monperrus Mar 31, 2018
8d609bd
little documentation changes
pvojtechovsky Mar 31, 2018
b248ecf
feature: PatternBuilder#matchInlinedStatements
pvojtechovsky Apr 3, 2018
5d333a0
up
monperrus Apr 7, 2018
5f0d791
up
monperrus Apr 7, 2018
b3d68cd
up
monperrus Apr 7, 2018
5c8a03e
up
monperrus Apr 7, 2018
71712f6
up
monperrus Apr 7, 2018
34aaf91
up
monperrus Apr 7, 2018
e4157a4
added contract to #testGenerateMultiValues
pvojtechovsky Apr 7, 2018
410586e
up
monperrus Apr 15, 2018
215b3c2
Pattern is Consumable (to simplify API)
monperrus Apr 15, 2018
14daf59
doc
monperrus Apr 15, 2018
0afd673
udpate test testGenerateMultiValues
monperrus Apr 15, 2018
1d9713e
up
monperrus Apr 15, 2018
d709a50
up
monperrus Apr 15, 2018
81a0e96
copy ElementPrinterHelper to test to keep test independent on spoon core
pvojtechovsky Apr 15, 2018
65dc0bc
fix to pass testTemplateInheritance
pvojtechovsky Apr 15, 2018
3aa1103
move tests related to Pattern from TemplateTest into PatternTest
monperrus Apr 15, 2018
a2e7415
up
monperrus Apr 15, 2018
4aa325c
up
monperrus Apr 15, 2018
e7bac51
end of review of testMatchIfElse
monperrus Apr 15, 2018
6304878
up
monperrus Apr 15, 2018
6aa7845
ParameterValueProvider moved to spoon.support.util
pvojtechovsky Apr 15, 2018
370e4d3
up
monperrus Apr 15, 2018
c00b65b
up
monperrus Apr 22, 2018
2567fc2
up
monperrus Apr 22, 2018
14f06aa
up
monperrus Apr 23, 2018
ca2c35b
Commit by Martin Monperrus on 01 May 2018
monperrus May 1, 2018
0b43f8b
fix test
pvojtechovsky May 12, 2018
488abca
fix test on MS Windows
pvojtechovsky May 12, 2018
c14eeb2
up
monperrus May 12, 2018
d679177
Merge branch 'master' into feaPattern
monperrus May 12, 2018
5dd9c92
up
monperrus May 13, 2018
198248d
move non public API classes to package ...internal...
pvojtechovsky May 14, 2018
7c9e350
up
monperrus May 21, 2018
c6dfc8d
up
monperrus May 21, 2018
898f878
up
monperrus May 21, 2018
15f2543
up
monperrus May 21, 2018
176468d
up
monperrus May 21, 2018
0a30676
delete ParameterValueProviderFactory
monperrus May 22, 2018
edd4b21
fix problems caused by refactoring
pvojtechovsky May 22, 2018
649f8a4
Merge branch 'feaPattern' of github.com:pvojtechovsky/spoon into feaP…
monperrus May 22, 2018
ba1b554
re-add removeSuperClass which is needed to create pattern from legacy
pvojtechovsky May 22, 2018
15c22f1
add test for Match#toString
monperrus May 22, 2018
e8d934d
add test for ImmutableMapImpl#asMap
monperrus May 22, 2018
c729798
remove untested useless code in StatementTemplate
monperrus May 22, 2018
b476963
fix javadoc bug
monperrus May 22, 2018
d132fc5
fix checkstyle
monperrus May 22, 2018
b363333
up
monperrus May 23, 2018
e9df1b8
up
monperrus May 23, 2018
1719d49
fix javadoc error
pvojtechovsky May 23, 2018
71a5ac3
move feature configurePatternParameters(Map) to byTemplateParameter and
pvojtechovsky May 23, 2018
e445995
Pattern generator methods moved to class Generator
pvojtechovsky May 23, 2018
8ee3507
fix javadoc error
pvojtechovsky May 23, 2018
5f40017
up
monperrus May 24, 2018
8091954
up
monperrus May 24, 2018
c957f78
up
monperrus May 24, 2018
9ce97bd
up
monperrus May 24, 2018
5632894
up
monperrus May 24, 2018
6ed144c
up
monperrus May 24, 2018
eecce4c
up
monperrus May 24, 2018
585a4df
remove ModelNode, and Pattern#getModelValueResolver
pvojtechovsky May 25, 2018
b30534d
up
monperrus May 25, 2018
67090bb
up
monperrus May 25, 2018
5e547d7
up
monperrus May 25, 2018
41a7559
up
monperrus May 25, 2018
e787e0c
Merge branch 'master' into feaPattern
monperrus May 25, 2018
f0fc029
cleaning and buig fixing
pvojtechovsky May 27, 2018
a15e5f8
ExtensionTemplate uses new generator - more tests covered
pvojtechovsky May 27, 2018
98adea5
Merge remote-tracking branch 'origin/master' into feaPattern
pvojtechovsky May 29, 2018
60d0381
remove SubstitutionVisitor
pvojtechovsky May 29, 2018
dd30d1e
use/test PatternBuilderHelper#setReturnExpressionOfMethod
pvojtechovsky May 29, 2018
fce2bc9
Merge branch 'master' into feaPattern
monperrus May 30, 2018
c9eee72
up
monperrus May 30, 2018
6ffea86
test optional generator and fix SwitchNode
pvojtechovsky May 31, 2018
6ef61b3
Merge remote-tracking branch 'origin/master' into feaPattern
pvojtechovsky Jun 9, 2018
1451e5b
improve metamodel test
pvojtechovsky Jun 9, 2018
c17e74c
Merge remote-tracking branch 'origin/master' into feaPattern
pvojtechovsky Jun 9, 2018
1483c51
unsettableProperty implies derived on leaf concept
pvojtechovsky Jun 9, 2018
89123b2
Pattern uses new metamodel
pvojtechovsky Jun 10, 2018
7e7f89f
move old metamodel to test to be able to check computed metamode
pvojtechovsky Jun 10, 2018
d7947c2
fix javadoc
pvojtechovsky Jun 10, 2018
bb782e9
remove metamodel test and MetamodelGenerator from this PR
pvojtechovsky Jun 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions doc/_data/sidebar_doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,20 @@ entries:
product: all
version: all

- title: Matchers
- title: Matcher
url: /matcher.html
audience: writers, designers
platform: all
product: all
version: all

- title: Pattern
url: /pattern.html
audience: writers, designers
platform: all
product: all
version: all

- title: Transforming source code
audience: writers, designers
platform: all
Expand All @@ -187,13 +194,28 @@ entries:
product: all
version: all

- title: Templates
- title: Generating source code
audience: writers, designers
platform: all
product: all
version: all

items:
- title: Template
url: /template_definition.html
audience: writers, designers
platform: all
product: all
version: all

items:
- title: Generator
url: '/pattern.html#generator'
audience: writers, designers
platform: all
product: all
version: all

- title: Testing
audience: writers, designers
platform: all
Expand Down
188 changes: 188 additions & 0 deletions doc/pattern.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
---
title: Spoon Patterns
---

Spoon patterns enables you to find code elements. A Spoon pattern is based on a one or several AST nodes, which represent the code to match, where some parts of the AST are pattern parameters. When a pattern is matched, one can access to the code matched in each pattern parameter.

The main classes of Spoon patterns are those in package `spoon.pattern`:

* classes: PatternBuilder, Pattern, Match, PatternBuilderHelper, PatternParameterConfigurator, InlinedStatementConfigurator
* eums: ConflictResolutionMode, Quantifier

Example usage:

```java
Factory spoonFactory = ...
//build a Spoon pattern
Pattern pattern = ... build a spoon pattern. For example for an method ...

//search for all occurences of the method in the root package
pattern.forEachMatch(spoonFactory.getRootPackage(), (Match match) -> {
Map<String, Object> parameters = match.getParametersAsMap();
CtMethod<?> matchingMethod = match.getMatchingElement(CtMethod.class);
String aNameOfMatchedMethod = parameters.get("methodName");
...
});
```

## PatternBuilder

To create a Spoon pattern, one must use `PatternBuilder`, which takes AST nodes as input, and **pattern parameters** are defined.


```java
// creates pattern from the body of method "matcher1"
Pattern t = PatternBuilder.create(
new PatternBuilderHelper(fooClass).setBodyOfMethod("matcher1").getPatternElements())
.configurePatternParameters()
.build();
```


This pattern matches all statements of the body of method `statement`, ie. a precondition to check that a list is smaller than a certain size.
This pattern has one single pattern parameter called `_col_`, which is automatically considered as a pattern parameter because it is declared outside of the AST node. This automatic configuration happens when `configurePatternParameters` is called.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keywords statement and _col_ are wrong with updated example

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you fix them directly? that would likely be more effective.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I started to do it before I wrote this comment, but then I had feeling like there is too many changes and I do not know your vision, so my fix might ho in wrong direction:
A) to remove comment about col
B) to re-add the example you removed
... I would prefer B), but you already removed it so, you probably prefer something else :-)


## Pattern

The main methods of `Pattern` are `getMatches` and `forEachMatch`.

```
List<Match> matches = pattern.getMatches(ctClass);
```

## Match

A `Match` represent a match of a pattern on a code elements.

The main methods are `getMatchingElement` and `getMatchingElements`.

## PatternBuilderHelper

`PatternBuilderHelper` is used to select AST nodes that would act as pattern. It is mainly used to get the body (method `setBodyOfMethod`) or the return expression of a method (method `setReturnExpressionOfMethod`) .

## PatternParameterConfigurator

To create pattern paramters, one uses a `PatternParameterConfigurator` as a lambda:


```java
//a pattern model
void method(String _x_) {
zeroOneOrMoreStatements();
System.out.println(_x_);
}

//a pattern definition
Pattern t = PatternBuilder.create(...select pattern model...)
.configureParameters(pb ->
// creating a pattern parameter called "firstParamName"
pb.parameter("firstParamName")
//...select which AST nodes are parameters...
//e.g. using parameter selector
.bySimpleName("zeroOneOrMoreStatements")
//...modify behavior of parameters...
//e.g. using parameter modifier
.setMinOccurence(0);

//... you can define as many parameters as you need...

// another parameter (all usages of variable "_x_"
pb.parameter("lastParamName").byVariable("_x_");
)
.build();
```

`ParametersBuilder` has many methods to create the perfect pattern parameters, incl:

* `byType(Class|CtTypeReference|String)` - all the references to the type defined by Class,
CtTypeReference or qualified name are considered as pattern parameter
* `byLocalType(CtType<?> searchScope, String localTypeSimpleName)` - all the types defined in `searchScope`
and having simpleName equal to `localTypeSimpleName` are considered as pattern parameter
* `byVariable(CtVariable|String)` - all read/write variable references to CtVariable
or any variable named with the provided simple name are considered as pattern parameter
* `byInvocation(CtMethod<?> method)` - all invocations of `method` are considered as pattern parameter
* `byVariable(CtVariable|String... variableName)` - each `variableName` is a name of a variable
which references instance of a class with fields. Each such field is considered as pattern parameter.
* `byFilter(Filter)` - any pattern model element, where `Filter.accept(element)` returns true is a pattern parameter.
* `byRole(CtRole role, Filter filter)` - the attribute defined by `role` of all
pattern model elements, where `Filter.accept(element)` returns true is a pattern parameter. It can be used to define a varible on any CtElement attribute. E.g. method modifiers or throwables, ...
* `byString(String name)` - all pattern model string attributes whose value is equal to `name` are considered as pattern parameter.This can be used to define full name of the methods and fields, etc.
* `bySubstring(String stringMarker)` - all pattern model string attributes whose value contains
whole string or a substring equal to `stringMarker`are pattern parameter. Note: only the `stringMarker` substring of the string value is substituted, other parts of string/element name are kept unchanged.
* `byNamedElement(String name)` - any CtNamedElement identified by it's simple name is a pattern parameter.
* `byReferenceName(String name)` - any CtReference identified by it's simple name is a pattern parameter.


Any parameter of a pattern can be configured like this:

* `setMinOccurence(int)` - defines minimal number of occurences of the value of this parameter during **matching**,
which is needed by matcher to accept that value.
* `setMinOccurence(0)` - defines optional parameter
* `setMinOccurence(1)` - defines mandatory parameter
* `setMinOccurence(n)` - defines parameter, whose value must be repeated at least n-times
* `setMaxOccurence(int)` - defines maximal number of occurences of the value of this parameter during **matching**,
which is accepted by matcher to accept that value.
* `setMatchingStrategy(Quantifier)` - defines how to matching engine arehave when two pattern nodes may accept the same value.
* `Quantifier#GREEDY` - Greedy quantifiers are considered "greedy" because they force the matcher to read in, or eat, the entire input prior to attempting the next match.
If the next match attempt (the entire input) fails, the matcher backs off the input by one and tries again,
repeating the process until a match is found or there are no more elements left to back off from.
* `Quantifier#RELUCTANT` - The reluctant quantifier takes the opposite approach: It start at the beginning of the input,
then reluctantly eat one character at a time looking for a match.
The last thing it tries is the entire input.
* `Quantifier#POSSESSIVE` - The possessive quantifier always eats the entire input string,
trying once (and only once) for a match. Unlike the greedy quantifiers, possessive quantifiers never back off,
even if doing so would allow the overall match to succeed.
* `setValueType(Class type)` - defines a required type of the value. If defined the pattern matched, will match only values which are assigneable from the provided `type`
* `matchCondition(Class<T> type, Predicate<T> matchCondition)` - defines a `Predicate`, whose method `boolean test(T)`,
are called by pattern matcher. Template matcher accepts that value only if `test` returns true for the value.
The `setValueType(type)` is called internally too, so match condition assures both a type of value and condition on value.
* `setContainerKind(ContainerKind)` - defines what container are used to store the value.
* `ContainerKind#SINGLE` - only single value is accepted as a parameter value.
It can be e.g. single String or single CtStatement, etc.
* `ContainerKind#LIST` - The values are always stored as `List`.
* `ContainerKind#SET` - The values are always stored as `Set`.
* `ContainerKind#MAP` - The values are always stored as `Map`.


## InlinedStatementConfigurator

It is possible to match inlined code, eg:

```java
System.out.println(1);
System.out.println(2);
System.out.println(3);
```

can be matched by

```java
for (int i=0; i<n; i++) {
System.out.println(n);
}
```

One mark code to be matched inlined using method `configureInlineStatements`, which receives a InlinedStatementConfigurator as follows:
```java
Pattern t = PatternBuilder.create(...select pattern model...)
//...configure parameters...
configureInlineStatements(ls ->
//...select to be inlined statements...
//e.g. by variable name:
ls.byVariableName("intValues")
).build();
```

The inlining methods are:

* `inlineIfOrForeachReferringTo(String varName)` - all CtForEach and CtIf statements
whose expression references variable named `varName` are understood as
inline statements
* `markAsInlined(CtForEach|CtIf)` - provided CtForEach or CtIf statement
is understood as inline statement

## Generator

All patterns can be used for code generation. The idea is that one calls `#generator()` on a pattern object to get a `Generator`. This class contains methods that takes as input a map of string,objects where each string key points to a pattern parameter name and each map value contains the element to be put in place of the pattern parameter.


32 changes: 27 additions & 5 deletions src/main/java/spoon/metamodel/Metamodel.java
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,18 @@ private Metamodel() {
}
}

/**
* @param clazz a {@link Class} of Spoon model
* @return {@link MetamodelConcept} which describes the `clazz`
*/
public MetamodelConcept getConcept(Class<? extends CtElement> clazz) {
MetamodelConcept mc = nameToConcept.get(getConceptName(clazz));
if (mc == null) {
throw new SpoonException("There is no Spoon metamodel concept for class " + clazz.getName());
}
return mc;
}

/**
* @return all {@link MetamodelConcept}s of spoon meta model
*/
Expand All @@ -289,13 +301,23 @@ public List<CtType<? extends CtElement>> getAllInstantiableMetamodelInterfaces()
* @return name of {@link MetamodelConcept}, which represents Spoon model {@link CtType}
*/
public static String getConceptName(CtType<?> type) {
String name = type.getSimpleName();
if (name.endsWith(CLASS_SUFFIX)) {
name = name.substring(0, name.length() - CLASS_SUFFIX.length());
}
return name;
return getConceptName(type.getSimpleName());
}

public static String getConceptName(Class<? extends CtElement> conceptClass) {
return getConceptName(conceptClass.getSimpleName());
}

/**
* @param simpleName a spoon model class or interface, whose concept name has to be returned
* @return name of {@link MetamodelConcept}, which represents Spoon model {@link CtType}
*/
private static String getConceptName(String simpleName) {
if (simpleName.endsWith(CLASS_SUFFIX)) {
simpleName = simpleName.substring(0, simpleName.length() - CLASS_SUFFIX.length());
}
return simpleName;
}

/**
* @param iface the interface of spoon model element
Expand Down
18 changes: 18 additions & 0 deletions src/main/java/spoon/metamodel/MetamodelConcept.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static spoon.metamodel.Metamodel.addUniqueObject;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
Expand Down Expand Up @@ -125,6 +126,23 @@ public Map<CtRole, MetamodelProperty> getRoleToProperty() {
return Collections.unmodifiableMap(role2Property);
}

/**
* @return Collection of all {@link MetamodelProperty} of current {@link MetamodelConcept}
* Note: actually is the order undefined
* TODO: return List in the same order like it is scanned by CtScanner
*/
public Collection<MetamodelProperty> getProperties() {
return Collections.unmodifiableCollection(role2Property.values());
}

/**
* @param role a {@link CtRole}
* @return {@link MetamodelProperty} for `role` of this concept
*/
public MetamodelProperty getProperty(CtRole role) {
return role2Property.get(role);
}

/**
* @return super types
*/
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/spoon/metamodel/MetamodelProperty.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
import spoon.reflect.declaration.CtNamedElement;
import spoon.reflect.factory.Factory;
import spoon.reflect.meta.ContainerKind;
import spoon.reflect.meta.RoleHandler;
import spoon.reflect.meta.impl.RoleHandlerHelper;
import spoon.reflect.path.CtRole;
import spoon.reflect.reference.CtTypeParameterReference;
import spoon.reflect.reference.CtTypeReference;
Expand Down Expand Up @@ -72,6 +74,8 @@ public class MetamodelProperty {
*/
private CtTypeReference<?> itemValueType;

private final RoleHandler roleHandler;

private Boolean derived;
private Boolean unsettable;

Expand Down Expand Up @@ -100,6 +104,7 @@ public class MetamodelProperty {
this.name = name;
this.role = role;
this.ownerConcept = ownerConcept;
roleHandler = RoleHandlerHelper.getRoleHandler((Class) ownerConcept.getMetamodelInterface().getActualClass(), role);
}

void addMethod(CtMethod<?> method) {
Expand Down Expand Up @@ -453,6 +458,10 @@ private CtTypeReference<?> getMapValueType(CtTypeReference<?> valueType) {
*/
public boolean isDerived() {
if (derived == null) {
if (getOwner().getKind() == ConceptKind.LEAF && isUnsettable()) {
derived = Boolean.TRUE;
return derived;
}
// by default it's derived
derived = Boolean.FALSE;

Expand Down Expand Up @@ -567,4 +576,26 @@ private static ContainerKind containerKindOf(Class<?> valueClass) {
return ContainerKind.SINGLE;
}

/**
* @return {@link RoleHandler} which can access runtime data of this Property
*/
public RoleHandler getRoleHandler() {
return this.roleHandler;
}

/**
* @param element an instance whose attribute value is read
* @return a value of attribute defined by this {@link MetamodelProperty} from the provided `element`
*/
public <T, U> U getValue(T element) {
return roleHandler.getValue(element);
}

/**
* @param element an instance whose attribute value is set
* @param value to be set value of attribute defined by this {@link MetamodelProperty} on the provided `element`
*/
public <T, U> void setValue(T element, U value) {
roleHandler.setValue(element, value);
}
}
Loading