11
22/*******************************************************************************
3- * Copyright 2011, 2016 Data Access Technologies, Inc. (Model Driven Solutions)
3+ * Copyright 2011- 2016 Data Access Technologies, Inc. (Model Driven Solutions)
44 * All rights reserved worldwide. This program and the accompanying materials
55 * are made available for use under the terms of the GNU General Public License
66 * (GPL) version 3 that accompanies this distribution and is available at
@@ -371,36 +371,48 @@ public List<ElementReference> parameterElements() {
371371 }
372372 return parameters ;
373373 }
374+
375+ public List <FormalParameter > parameters () {
376+ return this .parametersFor (null );
377+ }
374378
375- public List <FormalParameter > parameters () {
376- InvocationExpression self = this .getSelf ();
377- ElementReference referent = self .getReferent ();
379+ public List <FormalParameter > parametersFor (ElementReference referent ) {
380+ if (referent == null ) {
381+ referent = this .getSelf ().getReferent ();
382+ }
378383 List <FormalParameter > parameters = new ArrayList <FormalParameter >();
379- if (self .getIsBehavior () || self .getIsOperation ()) {
380- parameters = referent .getImpl ().getParameters ();
381- } else if (self .getIsAssociationEnd ()) {
382- ElementReference association = referent .getImpl ().getAssociation ();
383- String referentName = referent .getImpl ().getName ();
384- for (ElementReference property : association .getImpl ().getAssociationEnds ()) {
385- if (!property .getImpl ().getName ().equals (referentName )) {
386- FormalParameter parameter = parameterFromProperty (property );
387- parameter .setLower (1 );
388- parameter .setUpper (1 );
389- parameters .add (parameter );
384+ if (referent != null ) {
385+ if (referent .getImpl ().isBehavior () || referent .getImpl ().isOperation ()) {
386+ parameters = referent .getImpl ().getParameters ();
387+ } else if (referent .getImpl ().isAssociationEnd ()) {
388+ ElementReference association = referent .getImpl ().getAssociation ();
389+ String referentName = referent .getImpl ().getName ();
390+ for (ElementReference property : association .getImpl ().getAssociationEnds ()) {
391+ if (!property .getImpl ().getName ().equals (referentName )) {
392+ FormalParameter parameter = parameterFromProperty (property );
393+ parameter .setLower (1 );
394+ parameter .setUpper (1 );
395+ parameters .add (parameter );
396+ }
397+ }
398+ } else {
399+ for (ElementReference property : referent .getImpl ().getAttributes ()) {
400+ parameters .add (parameterFromProperty (property ));
390401 }
391- }
392- } else if (referent != null ) {
393- for (ElementReference property : referent .getImpl ().getAttributes ()) {
394- parameters .add (parameterFromProperty (property ));
395402 }
396403 }
397404 return parameters ;
398405 }
399-
406+
400407 // Returns the number of parameters, excluding return parameters.
401408 public int parameterCount () {
402- int n = this .parameters ().size ();
403- for (FormalParameter parameter : this .parameters ()) {
409+ return this .countParametersOf (null );
410+ }
411+
412+ public int countParametersOf (ElementReference referent ) {
413+ List <FormalParameter > parameters = parametersFor (referent );
414+ int n = parameters .size ();
415+ for (FormalParameter parameter : parameters ) {
404416 if ("return" .equals (parameter .getDirection ())) {
405417 n --;
406418 }
@@ -424,6 +436,12 @@ protected static FormalParameter parameterFromProperty(ElementReference property
424436 * after the tuple of the expression.
425437 **/
426438 public Map <String , AssignedSource > updateAssignmentMap () {
439+ // NOTE: Defer computation of referent until the assignments before
440+ // the feature and tuple are set.
441+ return this .updateAssignmentsFor (null );
442+ }
443+
444+ public Map <String , AssignedSource > updateAssignmentsFor (ElementReference referent ) {
427445 InvocationExpression self = this .getSelf ();
428446 FeatureReference feature = self .getFeature ();
429447 Tuple tuple = self .getTuple ();
@@ -434,13 +452,17 @@ public Map<String, AssignedSource> updateAssignmentMap() {
434452 }
435453 if (tuple != null ) {
436454 tuple .getImpl ().setAssignmentsBefore (assignments );
437- assignments = tuple .getImpl ().getAssignmentsAfterMap ();
455+ assignments = tuple .getImpl ().getAssignmentsAfterMap (referent );
438456 }
439457 return assignments ;
440- } // updateAssignments
458+ }
441459
442460 protected boolean parameterIsAssignableFrom (NamedExpression input ) {
443- FormalParameter namedParameter = this .parameterNamed (input .getName ());
461+ return this .parameterIsAssignableFrom (input , null );
462+ }
463+
464+ protected boolean parameterIsAssignableFrom (NamedExpression input , ElementReference referent ) {
465+ FormalParameter namedParameter = this .parameterNamed (input .getName (), referent );
444466 if (namedParameter == null ) {
445467 return false ;
446468 } else {
@@ -450,9 +472,13 @@ protected boolean parameterIsAssignableFrom(NamedExpression input) {
450472 namedParameter .getImpl ().isAssignableFrom (input .getExpression ());
451473 }
452474 }
453-
475+
454476 protected boolean parameterIsAssignableTo (NamedExpression output ) {
455- FormalParameter namedParameter = this .parameterNamed (output .getName ());
477+ return parameterIsAssignableTo (output , null );
478+ }
479+
480+ protected boolean parameterIsAssignableTo (NamedExpression output , ElementReference referent ) {
481+ FormalParameter namedParameter = this .parameterNamed (output .getName (), referent );
456482 if (namedParameter == null ||
457483 !(output instanceof OutputNamedExpression )) {
458484 return false ;
@@ -467,14 +493,45 @@ protected boolean parameterIsAssignableTo(NamedExpression output) {
467493 }
468494
469495 public FormalParameter parameterNamed (String name ) {
470- for (FormalParameter parameter : this .parameters ()) {
496+ return parameterNamed (name , null );
497+ }
498+
499+ public FormalParameter parameterNamed (String name , ElementReference referent ) {
500+ if (referent == null ) {
501+ referent = this .getSelf ().getReferent ();
502+ }
503+ for (FormalParameter parameter : this .parametersFor (referent )) {
471504 if (parameter .getName ().equals (name )) {
472505 return parameter ;
473506 }
474507 }
475508 return null ;
476509 }
477510
511+ public boolean isCompatibleWith (ElementReference referent ) {
512+ // NOTE: If referent is null, then the invocation referent is used,
513+ // which is cached, along with tuple inputs and outputs.
514+ InvocationExpression self = this .getSelf ();
515+ Tuple tuple = self .getTuple ();
516+ if (tuple == null ||
517+ tuple .getImpl ().size () > countParametersOf (referent )) {
518+ return false ;
519+ } else {
520+ this .updateAssignmentsFor (referent );
521+ for (NamedExpression input : tuple .getImpl ().deriveInput (referent )) {
522+ if (!parameterIsAssignableFrom (input , referent )) {
523+ return false ;
524+ }
525+ }
526+ for (NamedExpression output : tuple .getImpl ().deriveOutput (referent )) {
527+ if (!parameterIsAssignableTo (output , referent )) {
528+ return false ;
529+ }
530+ }
531+ }
532+ return true ;
533+ }
534+
478535 @ Override
479536 public void setCurrentScope (NamespaceDefinition currentScope ) {
480537 Tuple tuple = this .getSelf ().getTuple ();
0 commit comments