private void addConstructorInjectionStatements(final Injectable injectable, final Collection<Dependency> constructorDependencies, final List<Statement> createInstanceStatements) { final Object[] constructorParameterStatements = new Object[constructorDependencies.size()]; final List<Statement> dependentScopedRegistrationStatements = new ArrayList<>(constructorDependencies.size()); for (final Dependency dep : constructorDependencies) { processConstructorDependencyStatement(createInstanceStatements, constructorParameterStatements, dependentScopedRegistrationStatements, dep); } createInstanceStatements.add(declareFinalVariable("instance", injectable.getInjectedType(), newObject(injectable.getInjectedType(), constructorParameterStatements))); createInstanceStatements.addAll(dependentScopedRegistrationStatements); }
private List<Statement> contextLocalVarDeclarations(final Collection<MetaClass> scopeContextTypes) { final List<Statement> declarations = new ArrayList<>(); for (final MetaClass scopeContextImpl : scopeContextTypes) { if (!scopeContextImpl.isDefaultInstantiable()) { throw new RuntimeException( "The @ScopeContext " + scopeContextImpl.getName() + " must have a public, no-args constructor."); } declarations.add(declareFinalVariable(getContextVarName(scopeContextImpl), Context.class, newInstanceOf(scopeContextImpl))); } return declarations; }
@Override protected List<Statement> generateCreateInstanceStatements(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final DependencyGraph graph, final InjectionContext injectionContext) { final List<Statement> statements = new ArrayList<>(validators.size()+2); statements.add(Stmt.declareFinalVariable("dynamicValidator", DynamicValidator.class, ObjectBuilder.newInstanceOf(DynamicValidator.class))); bodyBlockBuilder.privateField("messageResolver", ValidationMessageResolver.class) .initializesWith(Stmt.invokeStatic(GWT.class, "create", Stmt.loadLiteral(ProviderValidationMessageResolver.class))).finish(); validators .stream() .map(validator -> addDynamicValidator(bodyBlockBuilder, validator)) .collect(Collectors.toCollection(() -> statements)); statements.add(loadVariable("dynamicValidator").returnValue()); return statements; }
@Override protected List<Statement> generateCreateInstanceStatements(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final DependencyGraph graph, final InjectionContext injectionContext) { final List<Statement> stmts = new ArrayList<>(2); final Injectable providerInjectable = getProviderInjectable(injectable); final MetaClass paramterizedProviderType = parameterizedAs(getProviderRawType(), typeParametersOf(injectable.getInjectedType())); stmts.add(declareFinalVariable("provider", paramterizedProviderType, lookupProviderStmt(providerInjectable, paramterizedProviderType))); stmts.add(declareFinalVariable("instance", injectable.getInjectedType(), invokeProviderStmt(loadVariable("provider")))); if (providerInjectable.getInjectedType().isAssignableTo(Disposer.class)) { stmts.add(loadVariable("this").invoke("setReference", loadVariable("instance"), "disposer", loadVariable("provider"))); } stmts.add(loadVariable("instance").returnValue()); return stmts; }
private void assignNewObjectWithZeroArgConstructor(final Injectable injectable, final List<Statement> createInstanceStatements) { final MetaConstructor noArgConstr = injectable.getInjectedType().getDeclaredConstructor(new MetaClass[0]); final Object newObjectStmt; if (noArgConstr.isPublic()) { newObjectStmt = newObject(injectable.getInjectedType()); } else { newObjectStmt = controller.exposedConstructorStmt(noArgConstr); } createInstanceStatements.add(declareFinalVariable("instance", injectable.getInjectedType(), newObjectStmt)); }
@SuppressWarnings("serial") private List<Statement> generateDataFieldMetas(final String dataFieldMetasVarName, final Decorable decorable) { final Map<String, DataField> annoMap = DataFieldCodeDecorator.aggregateDataFieldAnnotationMap(decorable, decorable.getType()); final List<Statement> stmts = new ArrayList<>(annoMap.size()+1); stmts.add(declareFinalVariable(dataFieldMetasVarName, new TypeLiteral<Map<String, DataFieldMeta>>() { }, newObject(parameterizedAs(HashMap.class, typeParametersOf(String.class, DataFieldMeta.class)), annoMap.size()))); annoMap .entrySet() .stream() .map(entry -> { final String fieldName = entry.getKey(); final DataField dataField = entry.getValue(); Statement dataFieldMetaInstance; if (dataField.attributeRules().length == 0 && dataField.defaultStrategy().equals(ConflictStrategy.USE_TEMPLATE)) { dataFieldMetaInstance = newObject(DataFieldMeta.class); } else { dataFieldMetaInstance = newObject(DataFieldMeta.class, loadLiteral(dataField.attributeRules()), loadLiteral(dataField.defaultStrategy())); } return loadVariable(dataFieldMetasVarName).invoke("put", fieldName, dataFieldMetaInstance); }) .collect(Collectors.toCollection(() -> stmts)); return stmts; }
@SuppressWarnings("serial") private List<Statement> generateDataFieldMetas(final String dataFieldMetasVarName, final Decorable decorable) { final Map<String, DataField> annoMap = DataFieldCodeDecorator.aggregateDataFieldAnnotationMap(decorable, decorable.getType()); final List<Statement> stmts = new ArrayList<>(annoMap.size()+1); stmts.add(declareFinalVariable(dataFieldMetasVarName, new TypeLiteral<Map<String, DataFieldMeta>>() { }, newObject(parameterizedAs(HashMap.class, typeParametersOf(String.class, DataFieldMeta.class)), annoMap.size()))); annoMap .entrySet() .stream() .map(entry -> { final String fieldName = entry.getKey(); final DataField dataField = entry.getValue(); Statement dataFieldMetaInstance; if (dataField.attributeRules().length == 0 && dataField.defaultStrategy().equals(ConflictStrategy.USE_TEMPLATE)) { dataFieldMetaInstance = newObject(DataFieldMeta.class); } else { dataFieldMetaInstance = newObject(DataFieldMeta.class, loadLiteral(dataField.attributeRules()), loadLiteral(dataField.defaultStrategy())); } return loadVariable(dataFieldMetasVarName).invoke("put", fieldName, dataFieldMetaInstance); }) .collect(Collectors.toCollection(() -> stmts)); return stmts; }
private void processConstructorDependencyStatement(final List<Statement> createInstanceStatements, final Object[] constructorParameterStatements, final List<Statement> dependentScopedRegistrationStatements, final Dependency dep) { final Injectable depInjectable = dep.getInjectable(); final ParamDependency paramDep = ParamDependency.class.cast(dep); final ContextualStatementBuilder injectedValue = getInjectedValue(depInjectable, paramDep); final String paramLocalVarName = getLocalVariableName(paramDep.getParameter()); createInstanceStatements.add(declareFinalVariable(paramLocalVarName, paramDep.getParameter().getType(), injectedValue)); if (dep.getInjectable().getWiringElementTypes().contains(WiringElementType.DependentBean)) { dependentScopedRegistrationStatements.add(loadVariable("this").invoke("registerDependentScopedReference", loadVariable("instance"), loadVariable(paramLocalVarName))); } constructorParameterStatements[paramDep.getParamIndex()] = loadVariable(paramLocalVarName); }
private List<Statement> methodCreateInstanceStatements(final MetaMethod producingMember, final Injectable producerInjectable, final Injectable producedInjectable, final Collection<Dependency> paramDeps, final ClassStructureBuilder<?> bodyBlockBuilder) { final List<Statement> stmts = new ArrayList<>(); controller.ensureMemberExposed(producingMember); if (!producingMember.isStatic()) { final Statement producerInstanceValue = loadVariable("contextManager").invoke("getInstance", producerInjectable.getFactoryName()); stmts.add(declareVariable(PRODUCER_INSTANCE, producerInjectable.getInjectedType(), producerInstanceValue)); stmts.add(loadVariable(PRODUCER_INSTANCE).assignValue(castTo(producerInjectable.getInjectedType(), invokeStatic(Factory.class, "maybeUnwrapProxy", loadVariable(PRODUCER_INSTANCE))))); } final List<Statement> depScopeRegistrationStmts = new ArrayList<>(); final Statement[] producerParams = generateProducerParams(producingMember, paramDeps, stmts, depScopeRegistrationStmts); final Statement invocation = controller.exposedMethodStmt(loadVariable(PRODUCER_INSTANCE), producingMember, producerParams); stmts.add(declareFinalVariable("instance", producedInjectable.getInjectedType(), invocation)); if (!producingMember.isStatic()) { stmts.add(setProducerInstanceReference()); if (producerInjectable.getWiringElementTypes().contains(WiringElementType.DependentBean)) { stmts.add(loadVariable("this").invoke("registerDependentScopedReference", loadVariable("instance"), loadVariable(PRODUCER_INSTANCE))); } } stmts.addAll(depScopeRegistrationStmts); stmts.add(loadVariable("instance").returnValue()); return stmts; }
private Statement[] generateProducerParams(final MetaMethod producingMember, final Collection<Dependency> paramDeps, final List<Statement> varDeclarationStmts, final List<Statement> depScopeRegistrationStmts) { // TODO validate params final Statement[] params = new Statement[producingMember.getParameters().length]; for (final Dependency dep : paramDeps) { final ParamDependency paramDep = (ParamDependency) dep; final ContextualStatementBuilder producerParamCreationStmt = generateProducerParamCreationStmt(paramDep); final String paramVarName = getLocalVariableName(paramDep.getParameter()); varDeclarationStmts.add(declareFinalVariable(paramVarName, paramDep.getParameter().getType(), producerParamCreationStmt)); if (paramDep.getInjectable().getWiringElementTypes().contains(WiringElementType.DependentBean)) { depScopeRegistrationStmts.add(loadVariable("this").invoke("registerDependentScopedReference", loadVariable("instance"), loadVariable(paramVarName))); } params[paramDep.getParamIndex()] = loadVariable(paramVarName); } return params; }
@Override public void generateDecorator(final Decorable decorable, final FactoryController controller) { final MetaMethod method = validateExceptionHandlingMethod(decorable); final boolean enclosingTypeDependent = decorable.isEnclosingTypeDependent(); final String handlerVar = method.getName() + "Handler"; final String cleanupRunnableVar = method.getName() + "HandlerCleanup"; final Statement setCleanupRefStmt = controller.setReferenceStmt(cleanupRunnableVar, Refs.get(cleanupRunnableVar)); final Statement getCleanupRefStmt = controller.getReferenceStmt(cleanupRunnableVar, Runnable.class); final List<Statement> initStmts = new ArrayList<>(Arrays.asList( declareAndInitHandlerVar(decorable, controller, handlerVar, enclosingTypeDependent), declareFinalVariable(cleanupRunnableVar, Runnable.class, addHandler(handlerVar)))); if (enclosingTypeDependent) { initStmts.add(setCleanupRefStmt); } final List<Statement> destructionStmts = Collections.singletonList(nestedCall(getCleanupRefStmt).invoke("run")); if (enclosingTypeDependent) { controller.addInitializationStatements(initStmts); controller.addDestructionStatements(destructionStmts); } else { controller.addFactoryInitializationStatements(initStmts); } }
private List<Statement> fieldCreateInstanceStatements(final MetaField producingMember, final Injectable producerInjectable, final Injectable producedInjectable, final ClassStructureBuilder<?> bodyBlockBuilder) { final List<Statement> stmts = new ArrayList<>(); controller.ensureMemberExposed(producingMember); if (!producingMember.isStatic()) { final Statement producerInstanceValue = loadVariable("contextManager").invoke("getInstance", producerInjectable.getFactoryName()); stmts.add(declareVariable(PRODUCER_INSTANCE, producerInjectable.getInjectedType(), producerInstanceValue)); stmts.add(loadVariable(PRODUCER_INSTANCE).assignValue(Stmt.castTo(producerInjectable.getInjectedType(), invokeStatic(Factory.class, "maybeUnwrapProxy", loadVariable(PRODUCER_INSTANCE))))); } final Statement invocation = controller.exposedFieldStmt(loadVariable(PRODUCER_INSTANCE), producingMember); stmts.add(declareFinalVariable("instance", producedInjectable.getInjectedType(), invocation)); if (!producingMember.isStatic()) { stmts.add(setProducerInstanceReference()); if (producerInjectable.getWiringElementTypes().contains(WiringElementType.DependentBean)) { stmts.add(loadVariable("this").invoke("registerDependentScopedReference", loadVariable("instance"), loadVariable(PRODUCER_INSTANCE))); } } stmts.add(loadVariable("instance").returnValue()); return stmts; }
private Statement declareAndInitHandlerVar(final Decorable decorable, final FactoryController controller, final String name, final boolean enclosingTypeDependent) { final MetaClass throwableConsumerClass = parameterizedAs(Consumer.class, typeParametersOf(Throwable.class)); final BlockBuilder<AnonymousClassStructureBuilder> initBuilder = newObject(throwableConsumerClass) .extend().publicOverridesMethod("accept", Parameter.of(Throwable.class, "t")); if (!enclosingTypeDependent) { final MetaClass enclosingType = decorable.getEnclosingInjectable().getInjectedType(); initBuilder.append(declareFinalVariable("instance", enclosingType, castTo(enclosingType, invokeStatic(Factory.class, "maybeUnwrapProxy", controller.contextGetInstanceStmt())))); } final ObjectBuilder initStmt = initBuilder.append(decorable.call(Refs.get("t"))).finish().finish(); final Statement handlerStatement = declareFinalVariable(name, throwableConsumerClass, initStmt); return handlerStatement; } }
private BlockBuilder<AnonymousClassStructureBuilder> getJsTypeSubscriptionCallback(final Decorable decorable, final FactoryController controller) { final MetaParameter parm = decorable.getAsParameter(); final MetaClass eventType = parm.getType().asBoxed(); final String parmClassName = eventType.getFullyQualifiedName(); final MetaClass callBackType = parameterizedAs(JsTypeEventObserver.class, typeParametersOf(eventType)); final AnonymousClassStructureBuilder callBack = Stmt.newObject(callBackType).extend(); BlockBuilder<AnonymousClassStructureBuilder> callBackBlock; final List<Statement> fireEventStmts = new ArrayList<>(); if (!decorable.isEnclosingTypeDependent()) { fireEventStmts.add(Stmt.declareFinalVariable("instance", decorable.getEnclosingInjectable().getInjectedType(), Stmt.invokeStatic(Factory.class, "maybeUnwrapProxy", controller.contextGetInstanceStmt()))); } fireEventStmts.add(decorable.call(Refs.get("event"))); callBackBlock = callBack.publicOverridesMethod("onEvent", Parameter.finalOf(eventType, "event")) .appendAll(fireEventStmts) .finish() .publicOverridesMethod("toString") ._(Stmt.load("JsTypeObserver: " + parmClassName).returnValue()); return callBackBlock; } }
@Override protected List<Statement> generateCreateInstanceStatements(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final DependencyGraph graph, final InjectionContext injectionContext) { final StatementBuilder anchorDeclaration = declareFinalVariable( "anchor", Anchor.class, castTo(Anchor.class, invokeStatic(Window.class, "getDocument") .invoke("createElement", "a"))); final ObjectBuilder clickListener = newObject(EventListener.class) .extend() .publicOverridesMethod("call", finalOf(Event.class, "event")) .append(navigationGoToInvocation(targetType)) .finish() .finish(); final ContextualStatementBuilder setClickListener = loadVariable("anchor").invoke("setOnclick", clickListener); final Statement returnValue = loadVariable("anchor").returnValue(); return Arrays.asList( anchorDeclaration, setClickListener, returnValue ); }
@Override protected List<Statement> generateCreateInstanceStatements(final ClassStructureBuilder<?> bodyBlockBuilder, final Injectable injectable, final DependencyGraph graph, final InjectionContext injectionContext) { final StatementBuilder anchorDeclaration = declareFinalVariable( "anchor", Anchor.class, castTo(Anchor.class, invokeStatic(Window.class, "getDocument") .invoke("createElement", "a"))); final ObjectBuilder clickListener = newObject(EventListener.class) .extend() .publicOverridesMethod("call", finalOf(Event.class, "event")) .append(navigationGoToInvocation(targetType)) .finish() .finish(); final ContextualStatementBuilder setClickListener = loadVariable("anchor").invoke("setOnclick", clickListener); final Statement returnValue = loadVariable("anchor").returnValue(); return Arrays.asList( anchorDeclaration, setClickListener, returnValue ); }
private void generateCommonSetter(final ClassStructureBuilder<?> classBuilder) { classBuilder.privateMethod(void.class, "changeAndFire", Parameter.of(String.class, "property"), Parameter.of(Object.class, "value")) .append(Stmt.declareFinalVariable("oldValue", Object.class, Stmt.loadVariable("this").invoke("get", loadVariable("property")))) .append(Stmt.loadVariable("this").invoke("set", loadVariable("property"), loadVariable("value"))) .append(agent().invoke("updateWidgetsAndFireEvent", false, loadVariable("property"), Variable.get("oldValue"), loadVariable("value"))) .finish(); }
private void generateCommonSetter(final ClassStructureBuilder<?> classBuilder) { classBuilder.privateMethod(void.class, "changeAndFire", Parameter.of(String.class, "property"), Parameter.of(Object.class, "value")) .append(Stmt.declareFinalVariable("oldValue", Object.class, Stmt.loadVariable("this").invoke("get", loadVariable("property")))) .append(Stmt.loadVariable("this").invoke("set", loadVariable("property"), loadVariable("value"))) .append(agent().invoke("updateWidgetsAndFireEvent", false, loadVariable("property"), Variable.get("oldValue"), loadVariable("value"))) .finish(); }
private Statement generateFactoryHandle(final Injectable injectable, @SuppressWarnings("rawtypes") final BlockBuilder curMethod) { final String handleVarName = "handleFor" + injectable.getFactoryName(); curMethod.append(declareFinalVariable(handleVarName, FactoryHandleImpl.class, ObjectBuilder.newInstanceOf(FactoryHandleImpl.class) .withParameters(loadLiteral(injectable.getInjectedType()), loadLiteral(injectable.getFactoryName()), loadLiteral(injectable.getScope()), loadLiteral(false), loadLiteral(injectable.getBeanName()), loadLiteral(!injectable.isContextual())))); curMethod.append(loadVariable(handleVarName).invoke("setAssignableTypes", getAssignableTypesArrayStmt(injectable))); if (!injectable.getQualifier().isDefaultQualifier()) { curMethod.append(loadVariable(handleVarName).invoke("setQualifiers", getAnnotationArrayStmt(injectable.getQualifier()))); } return loadVariable(handleVarName); }
public Statement maybeAddAssumedTypes(BlockBuilder<?> blockBuilder, String varName, Mapping mapping, Statement statement) { final MetaClass elementType = MarshallingGenUtil.getConcreteCollectionElementType(mapping.getType()); final MetaClass mapKeyType = MarshallingGenUtil.getConcreteMapKeyType(mapping.getType()); final MetaClass mapValueType = MarshallingGenUtil.getConcreteMapValueType(mapping.getType()); boolean assumedMapTypesSet = false; if (elementType != null) { blockBuilder.append(Stmt.loadVariable("a1").invoke("setAssumedElementType", elementType.getFullyQualifiedName())); } else if (mapKeyType != null && mapValueType != null) { blockBuilder.append(Stmt.loadVariable("a1").invoke("setAssumedMapKeyType", mapKeyType.getFullyQualifiedName())); blockBuilder.append(Stmt.loadVariable("a1") .invoke("setAssumedMapValueType", mapValueType.getFullyQualifiedName())); assumedMapTypesSet = true; } if (varName != null) { blockBuilder.append(Stmt.declareFinalVariable(varName, mapping.getTargetType(), statement)); } else { blockBuilder.append(statement); } if (assumedMapTypesSet) { blockBuilder.append(Stmt.loadVariable("a1").invoke("resetAssumedTypes")); } return (varName != null) ? Stmt.loadVariable(varName) : statement; }