Skip to content

Commit

Permalink
Do not include this code into master, this needs to be refactored when
Browse files Browse the repository at this point in the history
  • Loading branch information
Voiteh committed Oct 12, 2019
1 parent 7dd6828 commit 5db041c
Show file tree
Hide file tree
Showing 21 changed files with 199 additions and 20 deletions.
2 changes: 1 addition & 1 deletion example/example/depin/core/collector/example.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ void assertCollectorInjection(Collector<Integer> namingDoesntMatters){

shared void run(){
Depin{
scanner.scan({`package`});
scanner.dependencies({`package`});
}.inject(`assertCollectorInjection`);
}
2 changes: 1 addition & 1 deletion example/example/depin/core/named/example.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ void printInjection(Integer? integerSum){

shared void run(){
Depin{
scanner.scan({`package`});
scanner.dependencies({`package`});
}.inject(`printInjection`);
}
2 changes: 1 addition & 1 deletion example/example/depin/core/target/target.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ class TargetedInjection {

shared void run(){
Depin{
scanner.scan({`package`});
scanner.dependencies({`package`});
}.inject(`TargetedInjection.printInjection`);
}
2 changes: 1 addition & 1 deletion example/example/depin/core/toplevel/example.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import herd.depin.core {
}

shared void run() {
value depedencencyDeclarations=scanner.scan({`package`});
value depedencencyDeclarations=scanner.dependencies({`package`});
value result=Depin(depedencencyDeclarations).inject(`topLevelInjection`);
assert(topLevelValue.size==result);
}
24 changes: 23 additions & 1 deletion source/herd/depin/core/Depin.ceylon
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ceylon.language.meta.declaration {
FunctionOrValueDeclaration,
NestableDeclaration
NestableDeclaration,
ValueDeclaration
}

import herd.depin.core.internal {
Expand All @@ -13,6 +14,18 @@ import herd.depin.core.internal {
Handlers,
NotificationManager
}
import ceylon.language.meta {

type
}
import herd.depin.core.internal.util {

doCompleate=compleate
}
import ceylon.language.meta.model {

Value
}



Expand Down Expand Up @@ -71,6 +84,15 @@ shared class Depin {
assert(is Result result= dependency.resolve);
return result;
}
throws(`class Dependency.ResolutionError`, "Dependency can't be find for given compleatable declaration")
throws(`class CompleationException`, "Given target can't be compleated with provided dependencies ")
shared void compleate(Object target){
scanner.compleatables(target)
.map((Value<> element) => [element,dependencyFactory.create(element.declaration, true).resolve])
.each(([Value<>, Anything] element) => doCompleate(*element));


}


"Main functionality of this framework allowing to instantaite or call given [[Injectable]] using it's model.
Expand Down
2 changes: 1 addition & 1 deletion source/herd/depin/core/aliases.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ import ceylon.language.meta.declaration {
}
"Model which can be injected using [[Depin.inject]] method"
shared alias Injectable<Type> => ClassModel<Type>|ValueModel<Type>|FunctionModel<Type>;
"Range of decalarations which can be scanned using [[scanner.scan]] function"
"Range of decalarations which can be scanned using [[scanner.dependencies]] function"
shared alias Scope=> ClassDeclaration|FunctionOrValueDeclaration|Package|Module;
17 changes: 15 additions & 2 deletions source/herd/depin/core/annotations.ceylon
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import ceylon.language.meta.declaration {
FunctionOrValueDeclaration,
ConstructorDeclaration
ConstructorDeclaration,
ValueDeclaration
}
import ceylon.language.meta.model {

Attribute
}



see(`function compleatable`)
shared final annotation class CompleatableAnnotation() satisfies OptionalAnnotation<CompleatableAnnotation,ValueDeclaration,Attribute<>>{

}
"Used to mark a late attribute to be compleatead via [[Depin.compleate]] method, only late attributes will be compleated. Non late attributes will cause "
shared annotation CompleatableAnnotation compleatable() => CompleatableAnnotation();

see(`function fallback`)
shared final annotation class FallbackDecorator() satisfies Dependency.Decorator & OptionalAnnotation<FallbackDecorator,FunctionOrValueDeclaration>{
Expand Down Expand Up @@ -63,7 +76,7 @@ shared final annotation class DependencyAnnotation()
string => "dependency";
}

"Annotation used for creation of scannable declaration for [[scanner.scan]] function. Only declaration annotated with this annotation are taken in consideration when scanned. "
"Annotation used for creation of scannable declaration for [[scanner.dependencies]] function. Only declaration annotated with this annotation are taken in consideration when scanned. "
shared annotation DependencyAnnotation dependency() => DependencyAnnotation();

see(`function target`)
Expand Down
18 changes: 18 additions & 0 deletions source/herd/depin/core/errors.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

import ceylon.language.meta.model {

Value
}


"Thrown when compleation of an object can't be done"
shared class CompleationException extends Exception {

shared Value<> offendingValue;
shared new nonLateOrVariable(Value<> offendingValue) extends Exception("Counldn't compleate ``offendingValue``, it is not marked as late or variable. ") {
this.offendingValue=offendingValue;
}
shared new allreadyCompleated(Value<> offendingValue) extends Exception("Couldn't compleate ``offendingValue``, it is allready assigned and it's not a variable to be reasinged") {
this.offendingValue=offendingValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import herd.depin.core {

abstract class Defaulted() of defaulted{}
object defaulted extends Defaulted(){}
class DefaultedParameterDependency(Dependency.Definition definition,Dependencies tree) extends ParameterDependency(definition, tree){
class DefaultedReachingDependency(Dependency.Definition definition,Dependencies tree) extends ReachingDependency(definition, tree){

shared actual Anything resolve{
log.trace("Resolving defaulted parameter dependency: ``definition``");
Expand Down
12 changes: 6 additions & 6 deletions source/herd/depin/core/internal/DependencyFactory.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,19 @@ import herd.depin.core {
shared class DependencyFactory(DefinitionFactory definitionFactory,TargetSelector targetSelector,Dependencies tree) {


shared Dependency create(NestableDeclaration declaration,Boolean parameter) {
shared Dependency create(NestableDeclaration declaration,Boolean reaching) {

Dependency dependency;
if(parameter){
if(reaching){
Dependency.Definition definition = definitionFactory.create(declaration);
assert(is FunctionOrValueDeclaration declaration);
if(is OpenClassType declarationOpenType=declaration.openType,declarationOpenType.declaration==`class Collector`){
dependency=CollectorDependency(definition, tree);
}
else if(declaration.defaulted){
dependency= DefaultedParameterDependency(definition, tree);
dependency= DefaultedReachingDependency(definition, tree);
}else{
dependency=ParameterDependency(definition, tree);
dependency=ReachingDependency(definition, tree);
}
}
else{
Expand Down Expand Up @@ -69,7 +69,7 @@ shared class DependencyFactory(DefinitionFactory definitionFactory,TargetSelecto
switch(constructor)
case(is CallableConstructorDeclaration ){
value parameterDependencies = constructor.parameterDeclarations
.collect((FunctionOrValueDeclaration element) => ParameterDependency(definitionFactory.create(element), tree));
.collect((FunctionOrValueDeclaration element) => ReachingDependency(definitionFactory.create(element), tree));
dependency= FunctionalDependency( definition, containerDependency, parameterDependencies);
}
case(is ValueConstructorDeclaration){
Expand All @@ -81,7 +81,7 @@ shared class DependencyFactory(DefinitionFactory definitionFactory,TargetSelecto
throw FactorizationError(declaration, "Not supported");
}
}
log.debug("[Created Dependency]: ``dependency``, for declaration: ``declaration``, parameter: ``parameter``");
log.debug("[Created Dependency]: ``dependency``, for declaration: ``declaration``, parameter: ``reaching``");
return dependency;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import herd.depin.core.internal.util {



class ParameterDependency(Dependency.Definition definition, Dependencies tree) extends Dependency(definition) {
class ReachingDependency(Dependency.Definition definition, Dependencies tree) extends Dependency(definition) {
shared default Dependency? provide {
if (exists shadow= tree.get(definition)) {
return shadow;
Expand Down
25 changes: 25 additions & 0 deletions source/herd/depin/core/internal/util/compleate.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import herd.depin.core {
CompleationException
}

import ceylon.language.meta.model {
Value
}



throws (`class CompleationException`)
shared void compleate(Value<> val, Anything compleationValue) {

if(val.declaration.late ||val.declaration.variable){
try{
val.setIfAssignable(compleationValue);
}catch(InitializationError x){
throw CompleationException.allreadyCompleated(val);
}
}else{
throw CompleationException.nonLateOrVariable(val);
}


}
2 changes: 1 addition & 1 deletion source/herd/depin/core/module.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
To use this framework, one first needs to provide dependencies, for further injection.
It is done using [[scanner]] object. Scanning is gathering of methods and values declaration annotated with [[dependency]].
They can be nested in classes and member classes or top level, any formal declaration will be rejected.
The [[scanner.scan]] call would provide declarations for further use. This function, takes [[Scope]]s as paremeters.
The [[scanner.dependencies]] call would provide declarations for further use. This function, takes [[Scope]]s as paremeters.
[[Scope]] is range on which scanning would execute. When declaration are allready scaned they can be used for, [[Depin]] class object creation.
[[Depin]] will convert declarations into [[Dependency]]'ies and provide [[Depin.inject]] method.
Now the injection can happen. [[Depin.inject]] requires [[Injectable]] parameter which is alias for class, function or value model to which injection will happen.
Expand Down
24 changes: 22 additions & 2 deletions source/herd/depin/core/scanner.ceylon
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,18 @@ import ceylon.language.meta.declaration {
FunctionOrValueDeclaration,
ClassDeclaration,
Module,
Package
Package,
ValueDeclaration
}
import ceylon.language.meta.model {

Class,
Attribute,
Value
}
import ceylon.language.meta {

type
}

"Scans given scopes and produces declarations to be transformed into [[Dependency]]ies"
Expand Down Expand Up @@ -34,9 +45,18 @@ shared object scanner {
}
"Scans included [[inclusions]], reduced by excluded [[exclusions]] producing sequence of declarations for transformations into [[Dependency]].
Only declarations annotated with [[dependency]] and they container classes are taken in consideration"
shared FunctionOrValueDeclaration[] scan({Scope*} inclusions, {Scope*} exclusions=[]) {
shared FunctionOrValueDeclaration[] dependencies({Scope*} inclusions, {Scope*} exclusions=[]) {
[FunctionOrValueDeclaration+]|[] excluded = exclusions.flatMap((Scope element) => single(element)).sequence();
return inclusions.flatMap((Scope element) => single(element))
.filter((Declaration element) => !excluded.contains(element)).sequence();
}


shared Value<>[] compleatables(Object target){
return type(target).getAttributes<>(`CompleatableAnnotation`)
.map((Attribute<> element) => element.bind(target))
.sequence();
}


}
20 changes: 20 additions & 0 deletions test/test/herd/depin/engine/ceylon/MemberSetError.ceylon
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ceylon.test {

test,
ignore
}



class TestClass(){
shared late String attr;
}
ignore
shared test void checkMemberSet(){


value test=TestClass();
value val=`value TestClass.attr`;
val.memberSet(test, "bleh");

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import ceylon.test {
testExtension,
test
}
import depin.test.extension {
LoggingTestExtension
}
import test.herd.depin.engine.integration.compleation {
PositiveCompleation
}
import herd.depin.core {
Depin
}

testExtension (`class LoggingTestExtension`)
shared class SunnyCompleationTest() {

shared test
void shouldCompleateJohnDependency() {

value target = PositiveCompleation();
Depin({ `value fixture.person.john` }).compleate(target);
assert (target.john == fixture.person.john);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ shared class SunnyInjectionTest() {


shared test void shouldInjectExposedInterface(){
value declarations=scanner.scan({`package test.herd.depin.engine.integration.dependency.unshared`});
value declarations=scanner.dependencies({`package test.herd.depin.engine.integration.dependency.unshared`});
assert(Depin(declarations).inject(`ExposedTarget`).exposing.exposed==fixture.unshared.exposed);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import herd.depin.core {

compleatable
}
import test.herd.depin.engine.integration.injection {

Person
}

shared class AllreadyCompleatedCompleation(Person bleh) {
shared compleatable late Person john=bleh;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import herd.depin.core {

compleatable
}
import test.herd.depin.engine.integration.injection {

Person
}
shared class NonLateNegativeCompleation(shared compleatable Person john) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import test.herd.depin.engine.integration.injection {

Person
}
import herd.depin.core {

compleatable
}
shared class PositiveCompleation() {

shared compleatable late Person john;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shared package test.herd.depin.engine.integration.compleation;

0 comments on commit 5db041c

Please # to comment.