diff options
Diffstat (limited to 'extraplugins/alf09/src/org/eclipse/papyrus')
151 files changed, 15737 insertions, 0 deletions
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/Alf.xtext b/extraplugins/alf09/src/org/eclipse/papyrus/alf/Alf.xtext new file mode 100644 index 00000000000..614ce459b29 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/Alf.xtext @@ -0,0 +1,640 @@ +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +grammar org.eclipse.papyrus.alf.Alf with org.eclipse.xtext.common.Terminals + +generate alf "http://www.eclipse.org/papyrus/alf/Alf" + +/* + Test rule +*/ +Test : + ('testExpression' expression += Expression)* + ('testAssignmentExpression' assignExpression += AssignmentCompletion)* + ('testStatement' statements += Statement)* + ('testBlock' block = Block); + //('testStatementSequence' statement += StatementSequence)* ; + +/********************************* +* PrimitiveLiterals +**********************************/ + +LITERAL: + BOOLEAN_LITERAL | + NUMBER_LITERAL | + STRING_LITERAL +; + +BOOLEAN_LITERAL : + value = BooleanValue ; // (suffix = SuffixExpression) ? ; + +enum BooleanValue : + TRUE = 'true' | + FALSE = 'false' ; + +NUMBER_LITERAL : + INTEGER_LITERAL | UNLIMITED_LITERAL ; + +INTEGER_LITERAL : + value = IntegerValue ; // (suffix = SuffixExpression) ? ; + +UNLIMITED_LITERAL : + value = '*' ; // (suffix = SuffixExpression) ? ; + +terminal IntegerValue : + ('0' | '1'..'9' (('_')? '0'..'9')*) | //DECIMAL + (('0b' | '0B') '0'..'1' (('_')? '0'..'1')*) | // BINARY + (('0x'|'0X') ('0'..'9'|'a'..'f'|'A'..'F') (('_')? ('0'..'9'|'a'..'f'|'A'..'F'))*) | // HEX + ('0' ('_')? '0'..'7' (('_')? '0'..'7')*) // OCT +; + +STRING_LITERAL : + value = STRING ; // (suffix = SuffixExpression) ?; + +NameExpression : + (((prefixOp = ('++'|'--') (path=QualifiedNamePath)? id = ID)) + | + ((path=QualifiedNamePath)? id = ID + (invocationCompletion = Tuple + | sequenceConstructionCompletion = SequenceConstructionOrAccessCompletion + | postfixOp = ('++'|'--'))?)) (suffix = SuffixExpression) ? + ; + +QualifiedNamePath : + (namespace+=UnqualifiedName'::')+ +; + +UnqualifiedName : + name = ID (templateBinding = TemplateBinding)? +; + +TemplateBinding : + '<'bindings+=NamedTemplateBinding (',' bindings +=NamedTemplateBinding)*'>' +; + +NamedTemplateBinding : + formal = ID '=>' actual = QualifiedNameWithBinding +; + +QualifiedNameWithBinding : + id = ID (binding=TemplateBinding)? ('::' remaining=QualifiedNameWithBinding)?; + +Tuple : + {Tuple}'('(tupleElements += TupleElement (',' tupleElements+=TupleElement)*)?')' +; + +TupleElement : + argument = Expression +; + +/************** + * Expressions + **************/ + +Expression : + ConditionalTestExpression +; + +ConditionalTestExpression : + exp=ConditionalOrExpression ('?' whenTrue=ConditionalTestExpression ':' whenFalse=ConditionalTestExpression)? +; + +ConditionalOrExpression : + exp+=ConditionalAndExpression ('||' exp+=ConditionalAndExpression)* +; + +ConditionalAndExpression : + exp+=InclusiveOrExpression ('&&' exp+=InclusiveOrExpression)* +; + +InclusiveOrExpression : + exp+=ExclusiveOrExpression ('|' exp+=ExclusiveOrExpression)* +; + +ExclusiveOrExpression : + exp+=AndExpression ('^' exp+=AndExpression)* +; + +AndExpression : + exp+=EqualityExpression ('&' exp+=EqualityExpression)* +; + +EqualityExpression : + exp+=ClassificationExpression (op+=('==' | '!=') exp+=ClassificationExpression)* +; + +//enum EqualityOperator : +// EQUALS = '==' | +// NOT_EQUALS = '!=' +//; + +ClassificationExpression : + exp=RelationalExpression (op=('instanceof' | 'hastype') typeName=NameExpression)? +; + +//enum ClassificationOperator : +// INSTANCEOF = 'instanceof' | +// HASTYPE = 'hastype' +//; + +RelationalExpression : + left=ShiftExpression (op=('<' | '>' | '<=' | '>=') right=ShiftExpression)? +; + +//RelationalOperator : +// LOWER = '<' | +// UPPER = '>' | +// LOWER_EQUALS = '<=' | +// UPPER_EQUALS = '>=' +//; + +ShiftExpression : + exp+=AdditiveExpression (op=('<<' | '>>' | '>>>') exp+=AdditiveExpression)? +; + +//enum ShiftOperator : +// LSHIFT = '<<' | +// RSHIFT = '>>' | +// URSHIFT = '>>>' +//; + +AdditiveExpression : + exp+=MultiplicativeExpression (op+=('+' | '-') exp+=MultiplicativeExpression)* +; + +//enum AdditiveOp : +// PLUS = '+' | +// MINUS = '-' +//; + +MultiplicativeExpression : + exp+=UnaryExpression (op+=('*' | '/' | '%') exp+=UnaryExpression)* +; + +//enum MultiplicativeOp : +// MULT = '*' | +// DIV = '/' | +// MOD = '%' +//; + +UnaryExpression: + (op=('!'|'-'|'+'|'$'|'~'))? + exp=PrimaryExpression ; + +//PrimaryExpression : +// prefix = ValueSpecification (suffix = SuffixExpression)? +//; + +PrimaryExpression : + prefix = ValueSpecification +; + +SuffixExpression : + OperationCallExpression | + PropertyCallExpression | + LinkOperationExpression | + SequenceOperationExpression | + SequenceReductionExpression | + SequenceExpansionExpression | + ClassExtentExpression +; + +OperationCallExpression : + '.' operationName = ID tuple = Tuple (suffix = SuffixExpression)? +; + +// OperationCallExpressionWithoutDot : +// operationName = ID tuple = Tuple (suffix = SuffixExpression)? +// ; + +PropertyCallExpression : + '.' propertyName = ID ('[' index=Expression ']')? (suffix = SuffixExpression)? +; + +LinkOperationExpression : + '.' kind = LinkOperationKind tuple = LinkOperationTuple +; + +LinkOperationTuple : + '('linkOperationTupleElement += LinkOperationTupleElement (',' linkOperationTupleElement += LinkOperationTupleElement)*')' +; + +//LinkOperationTupleElement : +// objectOrRole = ID (('['roleIndex = Expression ']')? '=>' object = ID)? +//; + +LinkOperationTupleElement : + role = ID ('['roleIndex = Expression ']')? '=>' object = Expression +; + +enum LinkOperationKind : + CREATE = 'createLink' | + DESTROY = 'destroyLink' | + CLEAR = 'clearAssoc' +; + +SequenceOperationExpression : + //'->' operationName = ID tuple = Tuple (suffix = SuffixExpression) ? + '->' operationName = QualifiedNameWithBinding tuple = Tuple (suffix = SuffixExpression) ? +; + +SequenceReductionExpression : + '->' 'reduce' (isOrdered ?= 'ordered')? behavior = QualifiedNameWithBinding (suffix = SuffixExpression) ? +; + +SequenceExpansionExpression : + SelectOrRejectOperation | + CollectOrIterateOperation | + ForAllOrExistsOrOneOperation | + IsUniqueOperation +; + +SelectOrRejectOperation : + '->' op = SelectOrRejectOperator name = ID '('expr=Expression')' (suffix = SuffixExpression) ? +; + +enum SelectOrRejectOperator : + SELECT = 'select' | + REJECT = 'reject' +; + +CollectOrIterateOperation : + '->' op = CollectOrIterateOperator name = ID '('expr=Expression')' (suffix = SuffixExpression) ? +; + +enum CollectOrIterateOperator : + COLLECT = 'collect' | + ITERATE = 'iterate' +; + +ForAllOrExistsOrOneOperation : + '->' op = ForAllOrExistsOrOneOperator name = ID '('expr=Expression')' (suffix = SuffixExpression) ? +; + +enum ForAllOrExistsOrOneOperator : + FORALL = 'forAll' | + EXISTS = 'exists' | + ONE = 'one' +; + +IsUniqueOperation : + '->' 'isUnique' name = ID '('expr=Expression')' (suffix = SuffixExpression) ? +; + +ValueSpecification : + NameExpression | + LITERAL | + ThisExpression | + SuperInvocationExpression | + InstanceCreationExpression | + ParenthesizedExpression | + NullExpression + ; + +NonLiteralValueSpecification : + NameExpression | + ParenthesizedExpression | + InstanceCreationExpression | + ThisExpression | + SuperInvocationExpression +; + +ParenthesizedExpression : + '('expOrTypeCast = Expression')' ((casted = NonLiteralValueSpecification) | (suffix = SuffixExpression))? +; + +NullExpression : + {NullExpression} 'null' +; + +ThisExpression : + {ThisExpression}'this' (suffix = SuffixExpression)? +; + +// SuperInvocationExpression : +// //{SuperInvocationExpression} 'super' ('.' qualifiedNameRoot = ID '::' qualifiedNameRemaining = NameExpression)? //(suffix = SuffixExpression) ? +// 'super' ('.' className = ID '::' operationCallWithoutDot = OperationCallExpressionWithoutDot | operationCall = OperationCallExpression) +//; + +SuperInvocationExpression : + //{SuperInvocationExpression} 'super' ('.' qualifiedNameRoot = ID '::' qualifiedNameRemaining = NameExpression)? //(suffix = SuffixExpression) ? + //'super' ('.' className = ID '::' operationCallWithoutDot = OperationCallExpressionWithoutDot | operationCall = OperationCallExpression) + //'super' ((tuple = Tuple) | + // ('.' (path = QualifiedNamePath) operation = ID tuple = Tuple)) + 'super' ((tuple = Tuple) | + ('.' operationName = QualifiedNameWithBinding tuple = Tuple)) +; + +//InstanceCreationExpression : + //'new' constructor=QualifiedNameWithBinding + // (tuple = Tuple | sequenceConstuctionCompletion = SequenceConstructionCompletion) (suffix = SuffixExpression) ? + //'new' constructor=QualifiedNameWithBinding + // tuple = Tuple (suffix = SuffixExpression) ? +//; + +InstanceCreationExpression : + //'new' constructor=QualifiedNameWithBinding + // (tuple = Tuple | sequenceConstuctionCompletion = SequenceConstructionCompletion) (suffix = SuffixExpression) ? + 'new' constructor=QualifiedNameWithBinding + tuple = InstanceCreationTuple (suffix = SuffixExpression) ? +; + +InstanceCreationTuple : + {InstanceCreationTuple}'('(instanceCreationTupleElement += InstanceCreationTupleElement (',' instanceCreationTupleElement += InstanceCreationTupleElement)*)?')' +; + +//LinkOperationTupleElement : +// objectOrRole = ID (('['roleIndex = Expression ']')? '=>' object = ID)? +//; + +InstanceCreationTupleElement : + role = ID '=>' object = Expression +; + +SequenceConstructionOrAccessCompletion : + (multiplicityIndicator ?= '[' ((accessCompletion = AccessCompletion) | sequenceCompletion = PartialSequenceConstructionCompletion)) | + (expression = SequenceConstructionExpression) +; + +AccessCompletion : + accessIndex = Expression ']' +; + +PartialSequenceConstructionCompletion : + ']' expression = SequenceConstructionExpression +; + +//SequenceConstructionCompletion : +// (multiplicityIndicator ?= '['']')? expression = SequenceConstructionExpression +//; + +SequenceConstructionExpression : + '{'sequenceElement+=SequenceElement + ((',' sequenceElement+=SequenceElement)* | ('..' rangeUpper=Expression)) + '}' +; + +SequenceElement : + Expression | SequenceConstructionExpression +; + +ClassExtentExpression : + {ClassExtentExpression} '.' 'allInstances' '(' ')' +; + +/***************** + * Statements + ****************/ + +Block : + '{' {Block}(sequence = StatementSequence)? '}' +; + +StatementSequence : + (statements += DocumentedStatement)+ +; + +DocumentedStatement : + (comment = (ML_COMMENT | SL_COMMENT))? statement = Statement +; + +InlineStatement : + '/*@' 'inline' '('langageName = ID')' body = STRING '*/' +; + +AnnotatedStatement : + '//@' annotation = Annotation //block = Block + statement = Statement +; + +Statement : + (AnnotatedStatement | + InlineStatement | + BlockStatement | + EmptyStatement | + LocalNameDeclarationStatement | + IfStatement | + SwitchStatement | + WhileStatement | + DoStatement | + ForStatement | + BreakStatement | + ReturnStatement | + AcceptStatement | + ClassifyStatement | + InvocationOrAssignementOrDeclarationStatement | + SuperInvocationStatement | + ThisInvocationStatement | + InstanceCreationInvocationStatement) +; + +Annotation : + kind = AnnotationKind ('('args += ID (',' args += ID)* ')')? +; + +enum AnnotationKind : + ISOLATED = 'isolated' | + DETERMINED = 'determined' | + ASSURED = 'assured' | + PARALLEL = 'parallel' +; + + + +BlockStatement : + block = Block +; + +EmptyStatement : + {EmptyStatement} ';' +; + +LocalNameDeclarationStatement : + 'let' varName = ID ':' + type = QualifiedNameWithBinding + (multiplicityIndicator?='[' ']')? + //'=' init = Expression ';' + '=' init = SequenceElement ';' +; + +IfStatement : + 'if' sequentialClausses = SequentialClauses ( finalClause = FinalClause )? ; + +SequentialClauses : + conccurentClauses += ConcurrentClauses + ( 'else' 'if' conccurentClauses += ConcurrentClauses )* ; + +ConcurrentClauses : + nonFinalClause += NonFinalClause + ( 'or' 'if' nonFinalClause += NonFinalClause )* ; + +NonFinalClause : + '(' condition = Expression ')' block = Block ; + +FinalClause : + 'else' block = Block ; + + +SwitchStatement : + 'switch' '(' expression = Expression ')' '{' + ( switchClause += SwitchClause )* + ( defaultClause = SwitchDefaultClause )? + '}' ; + +SwitchClause : + switchCase += SwitchCase ( switchCase += SwitchCase )* statementSequence = NonEmptyStatementSequence ; + +SwitchCase : + 'case' expression = Expression ':' ; + +SwitchDefaultClause : + 'default' ':' statementSequence = NonEmptyStatementSequence ; + +NonEmptyStatementSequence : + ( statement += DocumentedStatement )+ ; + +/* WHILE STATEMENTS */ +WhileStatement : + 'while' '(' condition = Expression ')' block = Block ; + +/* DO STATEMENTS */ +DoStatement : + 'do' block = Block 'while' '(' condition = Expression ')' ';' ; + +/* FOR STATEMENTS */ +ForStatement : + 'for' '(' control = ForControl ')' block = Block ; + +ForControl : + loopVariableDefinition += LoopVariableDefinition( ',' loopVariableDefinition += LoopVariableDefinition )* ; + +LoopVariableDefinition : + (name = ID 'in' expression1 = Expression ( '..' expression2 = Expression )?) + | (type = QualifiedNameWithBinding name = ID ':' expression = Expression) ; + +/* BREAK STATEMENTS */ +BreakStatement : + {BreakStatement}'break' ';' ; + +/* RETURN STATEMENTS */ +ReturnStatement : + 'return' expression = Expression ';' ; + +/* ACCEPT STATEMENTS */ +AcceptStatement : + clause = AcceptClause + ( simpleAccept = SimpleAcceptStatementCompletion + | compoundAccept = CompoundAcceptStatementCompletion ) ; + +SimpleAcceptStatementCompletion : + {SimpleAcceptStatementCompletion}';' ; + +CompoundAcceptStatementCompletion : + block = Block ( 'or' acceptBlock += AcceptBlock )* ; + +AcceptBlock : + clause = AcceptClause block = Block ; + +AcceptClause : + 'accept' '(' ( name = ID ':' )? qualifiedNameList = QualifiedNameList ')' ; + +/* CLASSIFY STATEMENTS */ +ClassifyStatement : + 'classify' expression = Expression clause = ClassificationClause ';' ; + +ClassificationClause : + classifyFromClause = ClassificationFromClause ( classifyToClause = ClassificationToClause )? + | ( reclassyAllClause = ReclassifyAllClause )? classifyToClause = ClassificationToClause ; + +ClassificationFromClause : + 'from' qualifiedNameList = QualifiedNameList ; + +ClassificationToClause : + 'to' qualifiedNameList = QualifiedNameList ; + +ReclassifyAllClause : + {ReclassifyAllClause}'from' '*' ; + +QualifiedNameList : + qualifiedName += QualifiedNameWithBinding ( ',' qualifiedName += QualifiedNameWithBinding )* ; + +InvocationOrAssignementOrDeclarationStatement : + typePart_OR_assignedPart_OR_invocationPart = NameExpression + //(suffixCompletion = SuffixCompletion)? + ((variableDeclarationCompletion = VariableDeclarationCompletion) | + (assignmentCompletion = AssignmentCompletion))? ';' +; + +SuperInvocationStatement : + _super = SuperInvocationExpression ';'//(suffix = SuffixCompletion)? ';' +; + +ThisInvocationStatement : + //_this = ThisExpression suffix = SuffixCompletion (assignmentCompletion = AssignmentCompletion)? ';' + _this = ThisExpression (assignmentCompletion = AssignmentCompletion)? ';' +; + +InstanceCreationInvocationStatement : + _new = InstanceCreationExpression ';' //(suffix = SuffixCompletion)? ';' +; + +//SuffixCompletion : +// suffix = SuffixExpression +//; + +VariableDeclarationCompletion : + (multiplicityIndicator ?= '[' ']')? variableName = ID initValue = AssignmentCompletion +; + +AssignmentCompletion : + op=AssignmentOperator rightHandSide = SequenceElement + //op=('=' | '+=' | '-=' | '*=' | '%=' | '/=' | '&=' | + // '|=' | '^=' | '<<=' | '>>=' | '>>>=') rightHandSide = Expression +; + +enum AssignmentOperator : + ASSIGN = '=' | + PLUSASSIGN = '+=' | + MINUSASSIGN = '-=' | + MULTASSIGN = '*=' | + MODASSIGN = '%=' | + DIVASSIGN = '/=' | + ANDASSIGN = '&=' | + ORASSIGN = '|=' | + XORASSIGN = '^=' | + LSHIFTASSIGN = '<<=' | + RSHIFTASSIGN = '>>=' | + URSHIFTASSIGN = '>>>=' +; + +/**************** +* Terminals +*****************/ + +//terminal DOUBLE_COLON : '::' ; + +terminal ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* | ('\'' -> '\'') ; +terminal STRING : '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'"'|"'"|'\\') | !('\\'|'"') )* '"' ; +terminal ML_COMMENT : '/*' !('@') -> '*/'; +terminal SL_COMMENT : '//' !('\n'|'\r'|'@')* ('\r'? '\n')?; + +//terminal IDENTIFIER : ID ; +//terminal IDENTIFIER : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* | ('\'' -> '\'') ; + +//terminal DOCUMENTATION_COMMENT : '/*' -> '*/' ; + +//terminal ML_COMMENT : '/°' -> '°/'; +//terminal SL_COMMENT : '°°' !('\n'|'\r')* ('\r'? '\n')?; + +//terminal WS : (' '|'\t'|'\r'|'\n')+;
\ No newline at end of file diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/AlfRuntimeModule.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/AlfRuntimeModule.java new file mode 100644 index 00000000000..1eee1999feb --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/AlfRuntimeModule.java @@ -0,0 +1,22 @@ +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.alf; + +/** + * Use this class to register components to be used at runtime / without the Equinox extension registry. + */ +public class AlfRuntimeModule extends org.eclipse.papyrus.alf.AbstractAlfRuntimeModule { + +} + diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/AlfStandaloneSetup.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/AlfStandaloneSetup.java new file mode 100644 index 00000000000..d8324e4296e --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/AlfStandaloneSetup.java @@ -0,0 +1,27 @@ +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +package org.eclipse.papyrus.alf; + +/** + * Initialization support for running Xtext languages + * without equinox extension registry + */ +public class AlfStandaloneSetup extends AlfStandaloneSetupGenerated{ + + public static void doSetup() { + new AlfStandaloneSetup().createInjectorAndDoEMFRegistration(); + } +} + diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/Copy (2) of Alf.xtext b/extraplugins/alf09/src/org/eclipse/papyrus/alf/Copy (2) of Alf.xtext new file mode 100644 index 00000000000..918d55e86ad --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/Copy (2) of Alf.xtext @@ -0,0 +1,583 @@ +/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +grammar org.eclipse.papyrus.alf.Alf with org.eclipse.xtext.common.Terminals + +generate alf "http://www.eclipse.org/papyrus/alf/Alf" + +/* + Test rule +*/ +Test : + ('testExpression' expression += Expression)* + ('testAssignmentExpression' assignExpression += AssignmentCompletion)* + ('testStatement' statements += Statement)* + ('testBlock' block = Block); + //('testStatementSequence' statement += StatementSequence)* ; + + +/********************************* +* PrimitiveLiterals +**********************************/ + +LITERAL: + BOOLEAN_LITERAL | + NUMBER_LITERAL | + STRING_LITERAL +; + +BOOLEAN_LITERAL : + value = BooleanValue ; + +enum BooleanValue : + TRUE = 'true' | + FALSE = 'false' ; + +NUMBER_LITERAL : + INTEGER_LITERAL | UNLIMITED_LITERAL ; + +INTEGER_LITERAL : + value = IntegerValue ; + +UNLIMITED_LITERAL : + value = '*' ; + +terminal IntegerValue : + ('0' | '1'..'9' (('_')? '0'..'9')*) | //DECIMAL + (('0b' | '0B') '0'..'1' (('_')? '0'..'1')*) | // BINARY + (('0x'|'0X') ('0'..'9'|'a'..'f'|'A'..'F') (('_')? ('0'..'9'|'a'..'f'|'A'..'F'))*) | // HEX + ('0' ('_')? '0'..'7' (('_')? '0'..'7')*) // OCT +; + +STRING_LITERAL : + value = STRING ; + +NameExpression : + ((prefixOp = ('++'|'--') (path=QualifiedNamePath)? id = ID)) + | + ((path=QualifiedNamePath)? id = ID + (invocationCompletion = Tuple + | sequenceConstructionCompletion = SequenceConstructionOrAccessCompletion + | postfixOp = ('++'|'--'))?) ; + +QualifiedNamePath : + (namespace+=UnqualifiedName'::')+ +; + +UnqualifiedName : + name = ID (templateBinding = TemplateBinding)? +; + +TemplateBinding : + '<'bindings+=NamedTemplateBinding (',' bindings +=NamedTemplateBinding)*'>' +; + +NamedTemplateBinding : + formal = ID '=>' actual = QualifiedNameWithBinding +; + +QualifiedNameWithBinding : + id = ID (binding=TemplateBinding)? ('::' remaining=QualifiedNameWithBinding)?; + +Tuple : + {Tuple}'('(tupleElements += TupleElement (',' tupleElements+=TupleElement)*)?')' +; + +TupleElement : + argument = Expression +; + +/************** + * Expressions + **************/ + +enum AssignmentOperator : + ASSIGN = '=' | + PLUSASSIGN = '+=' | + MINUSASSIGN = '-=' | + MULTASSIGN = '*=' | + MODASSIGN = '%=' | + DIVASSIGN = '/=' | + ANDASSIGN = '&=' | + ORASSIGN = '|=' | + XORASSIGN = '^=' | + LSHIFTASSIGN = '<<=' | + RSHIFTASSIGN = '>>=' | + URSHIFTASSIGN = '>>>=' +; + +Expression : + ConditionalTestExpression +; + +ConditionalTestExpression : + exp=ConditionalOrExpression ('?' whenTrue=ConditionalTestExpression ':' whenFalse=ConditionalTestExpression)? +; + +ConditionalOrExpression : + exp+=ConditionalAndExpression ('||' exp+=ConditionalAndExpression)* +; + +ConditionalAndExpression : + exp+=InclusiveOrExpression ('&&' exp+=InclusiveOrExpression)* +; + +InclusiveOrExpression : + exp+=ExclusiveOrExpression ('|' exp+=ExclusiveOrExpression)* +; + +ExclusiveOrExpression : + exp+=AndExpression ('^' exp+=AndExpression)* +; + +AndExpression : + exp+=EqualityExpression ('&' exp+=EqualityExpression)* +; + +EqualityExpression : + exp+=ClassificationExpression (op+=EqualityOperator exp+=ClassificationExpression)* +; + +enum EqualityOperator : + EQUALS = '==' | + NOT_EQUALS = '!=' +; + +ClassificationExpression : + exp=RelationalExpression (op=ClassificationOperator typeName=NameExpression)? +; + +enum ClassificationOperator : + INSTANCEOF = 'instanceof' | + HASTYPE = 'hastype' +; + +RelationalExpression : + left=ShiftExpression (op=RelationalOperator right=ShiftExpression)? +; + +RelationalOperator : + LOWER = '<' | + UPPER = '>' | + LOWER_EQUALS = '<=' | + UPPER_EQUALS = '>=' +; + +ShiftExpression : + exp+=AdditiveExpression (op=ShiftOperator exp+=AdditiveExpression)? +; + +enum ShiftOperator : + LSHIFT = '<<' | + RSHIFT = '>>' | + URSHIFT = '>>>' +; + +AdditiveExpression : + exp+=MultiplicativeExpression (op+=AdditiveOp exp+=MultiplicativeExpression)* +; + +enum AdditiveOp : + PLUS = '+' | + MINUS = '-' +; + +MultiplicativeExpression : + exp+=UnaryExpression (op+=MultiplicativeOp exp+=PrimaryExpression)* +; + +enum MultiplicativeOp : + MULT = '*' | + DIV = '/' | + MOD = '%' +; + +UnaryExpression: + (op=('!'|'-'|'+'|'$'|'~') | '(' cast = ID ')')? + exp=PrimaryExpression ; + +PrimaryExpression : + prefix = ValueSpecification (suffix = SuffixExpression)? +; + +SuffixExpression : + OperationCallExpression | + PropertyCallExpression | + LinkOperationExpression | + SequenceOperationExpression | + SequenceReductionExpression | + SequenceExpansionExpression | + ClassExtentExpression +; + +OperationCallExpression : + '.' operationName = ID tuple = Tuple (suffix = SuffixExpression)? +; + +PropertyCallExpression : + '.' propertyName = ID ('[' index=Expression ']')? (suffix = SuffixExpression)? +; + +LinkOperationExpression : + '.' kind = LinkOperationKind tuple = LinkOperationTuple +; + +LinkOperationTuple : + '('linkOperationTupleElement += LinkOperationTupleElement (',' linkOperationTupleElement += LinkOperationTupleElement)*')' +; + +LinkOperationTupleElement : + objectOrRole = ID (('['roleIndex = Expression ']')? '=>' object = ID)? +; + +enum LinkOperationKind : + CREATE = 'createLink' | + DESTROY = 'destroyLink' | + CLEAR = 'clearAssoc' +; + +SequenceOperationExpression : + '->' operationName = ID tuple = Tuple (suffix = SuffixExpression) ? +; + +SequenceReductionExpression : + '->' 'reduce' (isOrdered ?= 'ordered')? behavior = QualifiedNameWithBinding +; + +SequenceExpansionExpression : + SelectOrRejectOperation | + CollectOrIterateOperation | + ForAllOrExistsOrOneOperation | + IsUniqueOperation +; + +SelectOrRejectOperation : + '->' op = SelectOrRejectOperator name = ID '('expr=Expression')' +; + +enum SelectOrRejectOperator : + SELECT = 'select' | + REJECT = 'reject' +; + +CollectOrIterateOperation : + '->' op = CollectOrIterateOperator name = ID '('expr=Expression')' +; + +enum CollectOrIterateOperator : + COLLECT = 'collect' | + ITERATE = 'iterate' +; + +ForAllOrExistsOrOneOperation : + '->' op = ForAllOrExistsOrOneOperator name = ID '('expr=Expression')' +; + +enum ForAllOrExistsOrOneOperator : + FORALL = 'forAll' | + EXISTS = 'exists' | + ONE = 'one' +; + +IsUniqueOperation : + '->' 'isUnique' name = ID '('expr=Expression')' +; + +ValueSpecification : + NameExpression | + LITERAL | + ThisExpression | + SuperInvocationExpression | + InstanceCreationExpression | + ParenthesizedExpression | + NullExpression + ; + +ParenthesizedExpression : + '('Expression')' +; + +NullExpression : + {NullExpression} 'null' +; + +ThisExpression : + {ThisExpression}'this' +; + +SuperInvocationExpression : + {SuperInvocationExpression} 'super' ('.' qualifiedNameRoot = ID '::' qualifiedNameRemaining = NameExpression)? +; + +InstanceCreationExpression : + 'new' constructor=QualifiedNameWithBinding + (tuple = Tuple | sequenceConstuctionCompletion = SequenceConstructionCompletion) +; + +SequenceConstructionOrAccessCompletion : + (multiplicityIndicator ?= '[' ((accessCompletion = AccessCompletion) | sequenceCompletion = PartialSequenceConstructionCompletion)) | + (expression = SequenceConstructionExpression) +; + +AccessCompletion : + accessIndex = Expression ']' +; + +PartialSequenceConstructionCompletion : + ']' expression = SequenceConstructionExpression +; + +SequenceConstructionCompletion : + (multiplicityIndicator ?= '['']')? expression = SequenceConstructionExpression +; + +SequenceConstructionExpression : + '{'sequenceElement+=SequenceElement + ((',' sequenceElement+=SequenceElement)* | ('..' rangeUpper=Expression)) + '}' +; + +SequenceElement : + Expression | SequenceConstructionExpression +; + +ClassExtentExpression : + {ClassExtentExpression} '.' 'allInstances' '(' ')' +; + +/***************** + * Statements + ****************/ + +Block : + '{' {Block}(sequence = StatementSequence)? '}' +; + +StatementSequence : + (statements += DocumentedStatement)+ +; + +InlineStatement : + '/*@' 'inline' langageName = ID body = STRING '*/' +; + +AnnotatedStatement : + '//@' annotation = Annotation block = Block +; + +DocumentedStatement : + (comment = (ML_COMMENT | SL_COMMENT))? statement = Statement +; + +Statement : + (AnnotatedStatement | + InlineStatement | + BlockStatement | + EmptyStatement | + LocalNameDeclarationStatement | + IfStatement | + SwitchStatement | + WhileStatement | + DoStatement | + ForStatement | + BreakStatement | + ReturnStatement | + AcceptStatement | + ClassifyStatement | + InvocationOrAssignementOrDeclarationStatement | + SuperInvocationStatement | + ThisInvocationStatement | + InstanceCreationInvocationStatement) +; + +Annotation : + kind = AnnotationKind ('('args += ID (',' args += ID)* ')')? +; + +enum AnnotationKind : + ISOLATED = 'isolated' | + DETERMINED = 'determined' | + ASSURED = 'assured' | + PARALLEL = 'parallel' +; + + + +BlockStatement : + block = Block +; + +EmptyStatement : + {EmptyStatement} ';' +; + +LocalNameDeclarationStatement : + 'let' varName = ID ':' + type = QualifiedNameWithBinding + (multiplicityIndicator?='[' ']')? + '=' init = Expression ';' +; + +IfStatement : + 'if' sequentialClausses = SequentialClauses ( finalClause = FinalClause )? ; + +SequentialClauses : + conccurentClauses += ConcurrentClauses + ( 'else' 'if' conccurentClauses += ConcurrentClauses )* ; + +ConcurrentClauses : + nonFinalClause += NonFinalClause + ( 'or' 'if' nonFinalClause += NonFinalClause )* ; + +NonFinalClause : + '(' condition = Expression ')' block = Block ; + +FinalClause : + 'else' block = Block ; + + +SwitchStatement : + 'switch' '(' expression = Expression ')' '{' + ( switchClause += SwitchClause )* + ( defaultClause = SwitchDefaultClause )? + '}' ; + +SwitchClause : + switchCase += SwitchCase ( switchCase += SwitchCase )* statementSequence = NonEmptyStatementSequence ; + +SwitchCase : + 'case' expression = Expression ':' ; + +SwitchDefaultClause : + 'default' ':' statementSequence = NonEmptyStatementSequence ; + +NonEmptyStatementSequence : + ( statement += DocumentedStatement )+ ; + +/* WHILE STATEMENTS */ +WhileStatement : + 'while' '(' condition = Expression ')' block = Block ; + +/* DO STATEMENTS */ +DoStatement : + 'do' block = Block 'while' '(' condition = Expression ')' ';' ; + +/* FOR STATEMENTS */ +ForStatement : + 'for' '(' control = ForControl ')' block = Block ; + +ForControl : + loopVariableDefinition += LoopVariableDefinition( ',' loopVariableDefinition += LoopVariableDefinition )* ; + +LoopVariableDefinition : + (name = ID 'in' expression1 = Expression ( '..' expression2 = Expression )?) + | (type = QualifiedNameWithBinding name = ID ':' expression = Expression) ; + +/* BREAK STATEMENTS */ +BreakStatement : + {BreakStatement}'break' ';' ; + +/* RETURN STATEMENTS */ +ReturnStatement : + 'return' expression = Expression ';' ; + +/* ACCEPT STATEMENTS */ +AcceptStatement : + clause = AcceptClause + ( simpleAccept = SimpleAcceptStatementCompletion + | compoundAccept = CompoundAcceptStatementCompletion ) ; + +SimpleAcceptStatementCompletion : + {SimpleAcceptStatementCompletion}';' ; + +CompoundAcceptStatementCompletion : + block = Block ( 'or' acceptBlock += AcceptBlock )* ; + +AcceptBlock : + clause = AcceptClause block = Block ; + +AcceptClause : + 'accept' '(' ( name = ID ':' )? qualifiedNameList = QualifiedNameList ')' ; + +/* CLASSIFY STATEMENTS */ +ClassifyStatement : + 'classify' expression = Expression clause = ClassificationClause ';' ; + +ClassificationClause : + classifyFromClause = ClassificationFromClause ( classifyToClause = ClassificationToClause )? + | ( reclassyAllClause = ReclassifyAllClause )? classifyToClause = ClassificationToClause ; + +ClassificationFromClause : + 'from' qualifiedNameList = QualifiedNameList ; + +ClassificationToClause : + 'to' qualifiedNameList = QualifiedNameList ; + +ReclassifyAllClause : + {ReclassifyAllClause}'from' '*' ; + +QualifiedNameList : + qualifiedName += QualifiedNameWithBinding ( ',' qualifiedName += QualifiedNameWithBinding )* ; + +InvocationOrAssignementOrDeclarationStatement : + typePart_OR_assignedPart_OR_invocationPart = NameExpression + (suffixCompletion = SuffixCompletion)? + ((variableDeclarationCompletion = VariableDeclarationCompletion) | + (assignmentCompletion = AssignmentCompletion))? ';' +; + +SuperInvocationStatement : + _super = SuperInvocationExpression (suffix = SuffixCompletion)? ';' +; + +ThisInvocationStatement : + _this = ThisExpression suffix = SuffixCompletion (assignmentCompletion = AssignmentCompletion)? ';' +; + +InstanceCreationInvocationStatement : + _new = InstanceCreationExpression (suffix = SuffixCompletion)? ';' +; + +SuffixCompletion : + suffix = SuffixExpression +; + +VariableDeclarationCompletion : + (multiplicityIndicator ?= '[' ']')? variableName = ID initValue = AssignmentCompletion +; + +AssignmentCompletion : + op=AssignmentOperator rightHandSide = Expression +; + +/**************** +* Terminals +*****************/ + +//terminal DOUBLE_COLON : '::' ; + +terminal ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* | ('\'' -> '\'') ; +terminal STRING : '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'"'|"'"|'\\') | !('\\'|'"') )* '"' ; +terminal ML_COMMENT : '/*' !('@')* '*/'; +terminal SL_COMMENT : '//' !('\n'|'\r'|'@')* ('\r'? '\n')?; + +//terminal IDENTIFIER : ID ; +//terminal IDENTIFIER : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* | ('\'' -> '\'') ; + +//terminal DOCUMENTATION_COMMENT : '/*' -> '*/' ; + +//terminal ML_COMMENT : '/°' -> '°/'; +//terminal SL_COMMENT : '°°' !('\n'|'\r')* ('\r'? '\n')?; + +//terminal WS : (' '|'\t'|'\r'|'\n')+;
\ No newline at end of file diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/Copy of Alf.xtext b/extraplugins/alf09/src/org/eclipse/papyrus/alf/Copy of Alf.xtext new file mode 100644 index 00000000000..ccc7288a678 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/Copy of Alf.xtext @@ -0,0 +1,1013 @@ +/***************************************************************************** + * Copyright (c) 2010 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ + +grammar org.eclipse.papyrus.alf.Alf with org.eclipse.xtext.common.Terminals + +generate alf "http://www.eclipse.org/papyrus/alf/Alf" + +/* + Test rule +*/ +Test : + ('testExpression' expression += Expression)* + ('testStatementSequence' statement += StatementSequence)* + ('testUnit' unit += UnitDefinition) *; + + +/********************************* +* PrimitiveLiterals +**********************************/ + +BOOLEAN_LITERAL : + value = BooleanValue ; +terminal BooleanValue : 'true' | 'false' ; + +NUMBER_LITERAL : + INTEGER_LITERAL | UNLIMITED_NATURAL ; + +INTEGER_LITERAL : + value = IntegerValue ; + +UNLIMITED_NATURAL : + value = '*' ; + +terminal IntegerValue : + ('0' | '1'..'9' (('_')? '0'..'9')*) | //DECIMAL + (('0b' | '0B') '0'..'1' (('_')? '0'..'1')*) | // BINARY + (('0x'|'0X') ('0'..'9'|'a'..'f'|'A'..'F') (('_')? ('0'..'9'|'a'..'f'|'A'..'F'))*) | // HEX + ('0' ('_')? '0'..'7' (('_')? '0'..'7')*) // OCT + ; + +STRING_LITERAL : + value = STRING ; + +/********* +* UNITS * +*********/ +UnitDefinition : + ( namespaceDeclaration = NamespaceDeclaration )? + ( importDeclaration += ImportDeclaration )* + //( <DOCUMENTATION_COMMENT> )? =>> To be added + ( comment = DocumentationComment )? + stereotypeAnnotations = StereotypeAnnotations + namespaceDefinition = NamespaceDefinition ; + +DocumentationComment : + comment = ML_COMMENT ; + +StereotypeAnnotations : + {StereotypeAnnotations}( annotation += StereotypeAnnotation )* ; + +StereotypeAnnotation : + '@' stereotype = QualifiedName + ( '(' taggedValues = TaggedValues ')' )? ; + +TaggedValues : + QualifiedNameList + | TaggedValueList ; + +TaggedValueList : + taggedValue += TaggedValue ( "," taggedValue += TaggedValue )* ; + +TaggedValue : + name = Name '=>' value = LiteralExpression ; +//| ( <PLUS> | <MINUS> )? + +NamespaceDeclaration : + 'namespace' qualifiedName = QualifiedName ';' ; + +ImportDeclaration : + visibility = ImportVisibilityIndicator 'import' importReference = ImportReference ';' ; + +enum ImportVisibilityIndicator : + PUBLIC = 'public' | + PRIVATE = 'private' ; + +ImportReference : + colonQualifiedName = ColonQualifiedName ( '::' star='*' | aliasDefinition = AliasDefinition )? + | dotQualifiedName = DotQualifiedName ( '.' star='*' | aliasDefinition = AliasDefinition )? + | name = Name ( ( '::' | '.' ) star = '*' | alias = AliasDefinition )? ; + +AliasDefinition : + 'as' name = Name ; + +/* NAMESPACES */ +NamespaceDefinition : + PackageDefinition | ClassifierDefinition ; + +enum VisibilityIndicator : + PUBLIC = 'public' | + PRIVATE = 'private' | + PROTECTED = 'protected' ; + +/* PACKAGES */ +PackageDeclaration : + 'package' name = Name ; + +PackageDefinition : + declaration = PackageDeclaration body = PackageBody ; + +PackageDefinitionOrStub : + declaration = PackageDeclaration ( ';' | body = PackageBody ) ; + +PackageBody : + {PackageBody} '{'( packagedElement += PackagedElement )* '}' ; + +PackagedElement : + // TO be added( <DOCUMENTATION_COMMENT> )? + stereotypeAnnotations = StereotypeAnnotations + importVisibility = ImportVisibilityIndicator + packagedElementDefinition = PackagedElementDefinition ; + +PackagedElementDefinition : + PackageDefinitionOrStub + | ClassifierDefinitionOrStub ; + +/*************** +* CLASSIFIERS * +***************/ + +ClassifierDefinition : + ClassDefinition + | ActiveClassDefinition + | DataTypeDefinition + | EnumerationDefinition + | AssociationDefinition + | SignalDefinition + | ActivityDefinition ; + +ClassifierDefinitionOrStub : + ClassDefinitionOrStub + | ActiveClassDefinitionOrStub + | DataTypeDefinitionOrStub + | EnumerationDefinitionOrStub + | AssociationDefinitionOrStub + | SignalDefinitionOrStub + | ActivityDefinitionOrStub ; + +ClassifierSignature : + name = Name ( templateParameters = TemplateParameters )? + ( specializationClause = SpecializationClause )? ; + +TemplateParameters : + '<' classifierTemplateParameter += ClassifierTemplateParameter + ( ',' classifierTemplateParameter += ClassifierTemplateParameter )* '>' ; + +ClassifierTemplateParameter : + // To be added( <DOCUMENTATION_COMMENT> )? + name = Name + ( 'specializes' specialized = QualifiedName )? ; + +SpecializationClause : + 'specializes' specialized = QualifiedNameList ; + +/* CLASSES */ +ClassDeclaration : + ( abstract ?= 'abstract' )? 'class' signature = ClassifierSignature ; + +ClassDefinition : + declaration = ClassDeclaration body = ClassBody ; + +ClassDefinitionOrStub : + declaration = ClassDeclaration ( ';' | body = ClassBody ) ; + +ClassBody : + {ClassBody}'{' ( classMember += ClassMember )* '}' ; + +ClassMember : + // To be added( <DOCUMENTATION_COMMENT> )? + stereotypeAnnotations = StereotypeAnnotations + ( visibilityIndicator = VisibilityIndicator )? + classMemberDefinition = ClassMemberDefinition ; + +ClassMemberDefinition : + ClassifierDefinitionOrStub + | FeatureDefinitionOrStub ; + +/* ACTIVE CLASSES */ +ActiveClassDeclaration : + ( abstract ?= 'abstract' )? 'active' 'class' signature = ClassifierSignature ; + +ActiveClassDefinition : + declaration = ActiveClassDeclaration body = ActiveClassBody ; + +ActiveClassDefinitionOrStub : + declaration = ActiveClassDeclaration ( ';' | body = ActiveClassBody ) ; + +ActiveClassBody : + {ActiveClassBody}'{' ( activerClassMember += ActiveClassMember )* '}' + ( 'do' behaviorClause = BehaviorClause )? ; + +BehaviorClause : + Block | Name ; + +ActiveClassMember : + // To be added( <DOCUMENTATION_COMMENT> )? + stereotypeAnnotations = StereotypeAnnotations + ( visibilityIndicator = VisibilityIndicator )? + activeClassMemberDefinition = ActiveClassMemberDefinition ; + +ActiveClassMemberDefinition : + ClassMemberDefinition + | ActiveFeatureDefinitionOrStub ; + +/* DATA TYPES */ +DataTypeDeclaration : + ( abstract ?= 'abstract' )? 'datatype' signature = ClassifierSignature ; + +DataTypeDefinition : + declaration = DataTypeDeclaration body = StructuredBody ; + +DataTypeDefinitionOrStub : + declaration = DataTypeDeclaration ( ';' | body = StructuredBody ) ; + +StructuredBody : + {StructureBody}'{' ( structuredMember += StructuredMember )* '}' ; + +StructuredMember : + // To be added ( <DOCUMENTATION_COMMENT> )? + stereotypeAnnotations = StereotypeAnnotations ( public ?= 'public' )? propertyDefinition = PropertyDefinition ; + +/* ASSOCIATIONS */ +AssociationDeclaration : + ( abstract ?= 'abstract' )? 'assoc' signature = ClassifierSignature ; + +AssociationDefinition : + declaration = AssociationDeclaration body = StructuredBody ; + +AssociationDefinitionOrStub : + declaration = AssociationDeclaration ( ';' | body = StructuredBody ) ; + +/* ENUMERATIONS */ +EnumerationDeclaration : + 'enum' name = Name ( specializationClause = SpecializationClause )? ; + +EnumerationDefinition : + declaration = EnumerationDeclaration body = EnumerationBody ; + +EnumerationDefinitionOrStub : + declaration = EnumerationDeclaration ( ';' | body = EnumerationBody ) ; + +EnumerationBody : + '{' name += EnumerationLiteralName ( ',' name += EnumerationLiteralName )* '}' ; + +EnumerationLiteralName : + // To be added ( <DOCUMENTATION_COMMENT> )? + Name ; + +/* SIGNALS */ +SignalDeclaration : + ( abstract ?= 'abstract' )? 'signal' signature = ClassifierSignature ; + +SignalDefinition : + declaration = SignalDeclaration body = StructuredBody ; + +SignalDefinitionOrStub : + declaration = SignalDeclaration ( ';' | body = StructuredBody ) ; + +/* ACTIVITIES */ +ActivityDeclaration : + 'activity' name = Name ( templateParameters = TemplateParameters )? + formalParameters = FormalParameters ( ':' typePart = TypePart )? ; + +ActivityDefinition : + declaration = ActivityDeclaration body = Block ; + +ActivityDefinitionOrStub : + declaration = ActivityDeclaration ( ';' | body = Block ) ; + +FormalParameters : + {FormalParameters} '(' ( formalParameterList = FormalParameterList )? ')' ; + +FormalParameterList : + formalParameter += FormalParameter ( ',' formalParameter += FormalParameter )* ; + +FormalParameter : + // To be added ( <DOCUMENTATION_COMMENT> )? + stereotypeAnnotations = StereotypeAnnotations + direction = ParameterDirection + name = Name ':' type = TypePart ; + +enum ParameterDirection : + IN = 'in' | + OUT = 'out' | + INOUT = 'inout' ; + +/* FEATURES */ +FeatureDefinitionOrStub : + AttributeDefinition + | OperationDefinitionOrStub ; + +ActiveFeatureDefinitionOrStub : + ReceptionDefinition + | SignalReceptionDefinitionOrStub ; + +/* PROPERTIES */ +PropertyDefinition : + declaration = PropertyDeclaration ';' ; + +AttributeDefinition : + declaration = PropertyDeclaration ( attributeInitialize = AttributeInitializer )? ';' ; + +AttributeInitializer : + '=' expression = InitializationExpression ; + +PropertyDeclaration : + name = Name ':' ( 'compose' )? type = TypePart ; + +TypePart : + typeName = TypeName ( multiplicity = Multiplicity )? ; + +Multiplicity : + {Multiplicity} '[' ( range = MultiplicityRange )? ']' + ( ordered ?= 'ordered' ( nonUnique ?= 'nonUnique' )? | nonUnique ?='nonUnique' ( ordered ?= 'ordered' )? | sequence ?= 'sequence' )? ; + +MultiplicityRange : + ( lower = NUMBER_LITERAL '..' )? upper = NUMBER_LITERAL ; +//UnlimitedNaturalLiteral = <DECIMAL_LITERAL> | <STAR> + +/* OPERATIONS */ +OperationDeclaration : + ( abstract ?= 'abstract' )? name = Name formalParameters = FormalParameters + ( ':' returnType = TypePart )? ( redefinition = RedefinitionClause )? ; + +OperationDefinitionOrStub : + declaration = OperationDeclaration ( ';' | body = Block ) ; + +RedefinitionClause : + 'redefines' redefinedOperations = QualifiedNameList ; + +/* RECEPTIONS */ +ReceptionDefinition : + 'receive' signalName = QualifiedName ';' ; + +SignalReceptionDeclaration : + 'receive' 'signal' name = Name ( specializationClause = SpecializationClause )? ; + +SignalReceptionDefinitionOrStub : + declaration = SignalReceptionDeclaration ( ';' | body = StructuredBody ) ; + +/***************************** +* Statements +******************************/ + +StatementSequence : + {StatementSequence}( statement += DocumentedStatement )* ; + +DocumentedStatement : + //( <DOCUMENTATION_COMMENT> )? Statement =>>> to be taken into account + Statement ; + +Statement : + BlockStatement | + //AnnotatedStatement| + //InLineStatement | + LocalNameDeclarationOrExpressionStatement | + LocalNameDeclarationStatement | + IfStatement | + SwitchStatement | + WhileStatement | + ForStatement | + DoStatement | + BreakStatement | + ReturnStatement | + AcceptStatement | + ClassifyStatement | + EmptyStatement + ; + +/* BLOCK */ +Block : + '{' statementSequence = StatementSequence '}' ; + +/* ANNOTATED STATEMENTS */ +//AnnotatedStatement : +// '/@' (annotation = Annotations) '\n' statement = Statement ; +// +//Annotations : +// annotation += Annotation ( '@' annotation+= Annotation )* ; +// +//Annotation : +// id = ID ( '(' nameList = NameList ')' )? ; +// +//NameList : +// name += Name ( ',' name+=Name )* ; +// +///* IN-LINE STATEMENTS */ +//InLineStatement : +// '/*@' id=ID '(' name = Name ')' ; +// //<DOCUMENTATION_COMMENT> =>>> to be taken into account + +/* BLOCK STATEMENTS */ +BlockStatement : + block = Block ; + +/* EMPTY STATEMENTS */ +EmptyStatement : + {EmptyStatement} ';' ; + +/* LOCAL NAME DECLARATION AND EXPRESSION STATEMENTS */ +LocalNameDeclarationOrExpressionStatement : + qualifiedName = PotentiallyColonQualifiedName (qualifiednameToExpressionCompletion = NameToExpressionCompletion)? + ( ( multiplicityIndicator = MultiplicityIndicator )? name = Name nameDeclarationCompletion = LocalNameDeclarationStatementCompletion + | nameToExpressionCompletion = NameToExpressionCompletion ';' + ) + | nonNameExpression = NonNameExpression ';' ; + +LocalNameDeclarationStatement : + 'let' name = Name ':' type = TypeName ( multiplicityIndicator = MultiplicityIndicator )? + localNameDeclarationCompletion = LocalNameDeclarationStatementCompletion ; + +TypeName : + {TypeName}(qualifiedName = QualifiedName | 'any') ; + +LocalNameDeclarationStatementCompletion : + '=' initialization = InitializationExpression ';' ; + +InitializationExpression : + Expression + | SequenceInitializationExpression + | InstanceInitializationExpression ; + +InstanceInitializationExpression : + 'new' tuple = Tuple ; + +/* IF STATEMENTS */ +IfStatement : + 'if' sequentialClausses = SequentialClauses ( finalClause = FinalClause )? ; + +SequentialClauses : + conccurentClauses += ConcurrentClauses + ( 'else' 'if' conccurentClauses += ConcurrentClauses )* ; + +ConcurrentClauses : + nonFinalClause += NonFinalClause + ( 'or' 'if' nonFinalClause += NonFinalClause )* ; + +NonFinalClause : + '(' condition = Expression ')' block = Block ; + +FinalClause : + 'else' block = Block ; + +/* SWITCH STATEMENTS */ +SwitchStatement : + 'switch' '(' expression = Expression ')' '{' + ( switchClause += SwitchClause )* + ( defaultClause = SwitchDefaultClause )? + '}' ; + +SwitchClause : + switchCase += SwitchCase ( switchCase += SwitchCase )* statementSequence = NonEmptyStatementSequence ; + +SwitchCase : + 'case' expression = Expression ':' ; + +SwitchDefaultClause : + 'default' ':' statementSequence = NonEmptyStatementSequence ; + +NonEmptyStatementSequence : + ( statement += Statement )+ ; + // Should be: ( statement += DocumentedStatement )+ ; + +/* WHILE STATEMENTS */ +WhileStatement : + 'while' '(' condition = Expression ')' block = Block ; + +/* DO STATEMENTS */ +DoStatement : + 'do' block = Block 'while' '(' condition = Expression ')' ';' ; + +/* FOR STATEMENTS */ +ForStatement : + 'for' '(' control = ForControl ')' block = Block ; + +ForControl : + loopVariableDefinition += LoopVariableDefinition( ',' loopVariableDefinition += LoopVariableDefinition )* ; + +LoopVariableDefinition : + (name = Name 'in' expression1 = Expression ( '::' expression2 = Expression )?) + | (type = QualifiedName name = Name ':' expression = Expression) ; + +/* BREAK STATEMENTS */ +BreakStatement : + {BreakStatement}'break' ';' ; + +/* RETURN STATEMENTS */ +ReturnStatement : + 'return' expression = Expression ';' ; + +/* ACCEPT STATEMENTS */ +AcceptStatement : + clause = AcceptClause + ( simpleAccept = SimpleAcceptStatementCompletion + | compoundAccept = CompoundAcceptStatementCompletion ) ; + +SimpleAcceptStatementCompletion : + {SimpleAcceptStatementCompletion}';' ; + +CompoundAcceptStatementCompletion : + block = Block ( 'or' acceptBlock += AcceptBlock )* ; + +AcceptBlock : + clause = AcceptClause block = Block ; + +AcceptClause : + 'accept' '(' ( name = Name ':' )? qualifiedNameList = QualifiedNameList ')' ; + +/* CLASSIFY STATEMENTS */ +ClassifyStatement : + 'classify' expression = Expression clause = ClassificationClause ';' ; + +ClassificationClause : + classifyFromClause = ClassificationFromClause ( classifyToClause = ClassificationToClause )? + | ( reclassyAllClause = ReclassifyAllClause )? classifyToClause = ClassificationToClause ; + +ClassificationFromClause : + 'from' qualifiedNameList = QualifiedNameList ; + +ClassificationToClause : + 'to' qualifiedNameList = QualifiedNameList ; + +ReclassifyAllClause : + {ReclassifyAllClause}'from' '*' ; + +QualifiedNameList : + qualifiedName += QualifiedName ( ',' qualifiedName += QualifiedName )* ; + +/******************************** +* Names +**********************************/ + +Name : + id = ID ; + +QualifiedName : + unqualifiedName = UnqualifiedName ( completion = QualifiedNameCompletion)? ; + +//ADDED for implementation of QualifiedName +QualifiedNameCompletion : + ColonQualifiedNameCompletion | DotQualifiedNameCompletion ; +///////////////////////////////////////////////////// + +PotentiallyAmbiguousQualifiedName : + unqualifiedName = NameBinding ('::' colonCompletion += NameBinding)* ; +//Simplified with respect to the real spec (i.e. no template-based qualified name possible with the '.' notation) + +ColonQualifiedName : + unqualifiedName = UnqualifiedName completion = ColonQualifiedNameCompletion ; + +PotentiallyColonQualifiedName : + unqualifiedName = UnqualifiedName (completion = ColonQualifiedNameCompletion)? ; + +ColonQualifiedNameCompletion : + ( '::' binding += NameBinding )+ ; + +DotQualifiedName : + unqualifiedName = UnqualifiedName completion = DotQualifiedNameCompletion ; + +DotQualifiedNameCompletion : + ( '.' binding += NameBinding )+ ; + +UnqualifiedName : + NameBinding ; + +NameBinding : + name = Name ( templateBinding = TemplateBinding )? ; + +TemplateBinding : + '<' ( NamedTemplateBinding | PositionalTemplateBinding ) '>' ; + +PositionalTemplateBinding : + qualifiedName += QualifiedName ( ',' qualifiedName += QualifiedName )* ; + +NamedTemplateBinding : + substitution += TemplateParameterSubstitution ( ',' substitution += TemplateParameterSubstitution )* ; + +TemplateParameterSubstitution : + parameter = Name '=>' argument = QualifiedName ; + +/********************************* +* Expressions +**********************************/ + +Expression : + unary = UnaryExpression completion = ExpressionCompletion ; + +NonNameExpression : + nonNameUnary = NonNameUnaryExpression completion = ExpressionCompletion ; + +NameToExpressionCompletion : + ( nameToPrimary = NameToPrimaryExpression )? completion = PrimaryToExpressionCompletion ; + +PrimaryToExpressionCompletion : + postfixCompletion = PostfixExpressionCompletion completion = ExpressionCompletion ; + +ExpressionCompletion : + AssignmentExpressionCompletion | ConditionalExpressionCompletion ; + +/* PRIMARY EXPRESSIONS */ + +PrimaryExpression : + prefix = PrimaryExpressionPrefix + completion = PrimaryExpressionCompletion ; + +//ADDED for prefix of PrimaryExpression//////// +PrimaryExpressionPrefix : + ( NameOrPrimaryExpression | BaseExpression | ParenthesizedExpression ) ; +/////////////// + +BaseExpression : + LiteralExpression + | ThisExpression + | SuperInvocationExpression + | InstanceCreationOrSequenceConstructionExpression + | SequenceAnyExpression ; + +NameToPrimaryExpression : + '.' ( LinkOperationCompletion | ClassExtentExpressionCompletion ) + | SequenceConstructionExpressionCompletion + | BehaviorInvocation ; + +PrimaryExpressionCompletion : + {PrimaryExpressionCompletion}( completionItems += PrimaryExpressionCompletionItem)* ; + +//ADDED for PrimaryExpressionCompletion implem +PrimaryExpressionCompletionItem : + FeatureCompletion | SequenceOperationOrReductionOrExpansion | Index ; +FeatureCompletion : + feature = Feature (completion = FeatureInvocation)? ; +////////////////////////////////////////////////////////// + +/* LITERAL EXPRESSIONS */ +LiteralExpression : + BOOLEAN_LITERAL + | NUMBER_LITERAL + | STRING_LITERAL; + +/* NAME EXPRESSIONS */ +NameOrPrimaryExpression : + nameOrPrimary = PotentiallyAmbiguousQualifiedName ( toPrimary = NameToPrimaryExpression )? ; + +/* THIS EXPRESSIONS */ +ThisExpression : + {ThisExpression}'this' ( tuple = Tuple )? ; + +/* PARENTHESIZED EXPRESSIONS */ +ParenthesizedExpression : + '(' Expression ')' ; + +/* PROPERTY ACCESS EXPRESSIONS */ +Feature : + '.' nameBinding = NameBinding ; + +/* INVOCATION EXPRESSIONS */ +Tuple : + {Tuple}'(' + ( namedTupleList = NamedTupleExpressionList | ( positionalTupleList = PositionalTupleExpressionList )? ) ')' ; + + +PositionalTupleExpressionList : + expression = Expression positionalTupleListCompletion = PositionalTupleExpressionListCompletion ; + +PositionalTupleExpressionListCompletion : + {PositionalTupleExpressionListCompletion}( ',' expression += Expression )* ; + +NamedTupleExpressionList : + namedExpression += NamedExpression ( ',' namedExpressions += NamedExpression )* ; + +NamedExpression : + name = Name '=>' expression = Expression ; + +BehaviorInvocation : + Tuple ; + +FeatureInvocation : + Tuple ; + +SuperInvocationExpression : + 'super' ( '.' qualifiedName = QualifiedName )? tuple = Tuple ; + +/* INSTANCE CREATION EXPRESSIONS */ +InstanceCreationOrSequenceConstructionExpression : + 'new' qualifiedName = QualifiedName + completion = InstanceCreationOrSequenceConstructionExpressionCompletion ; + +//ADDED for implem of InstanceCreationOrSequenceConstructionExpression +InstanceCreationOrSequenceConstructionExpressionCompletion : + SequenceConstructionExpressionCompletion | Tuple ; +///////////////////////////////////////////////////// + +/* LINK OPERATION EXPRESSIONS */ +LinkOperationCompletion : + linkOperation = LinkOperation tuple = LinkOperationTuple ; + +enum LinkOperation : + CREATE ='createLink' + | DESTROY = 'destroyLink' + | CLEAR = 'clearAssoc' ; + +LinkOperationTuple : + {LinkOperationOrTuple}'(' + ( name = Name + ( index = Index + ( '=>' indexedNameCompletion = IndexedNamedExpressionListCompletion + | primaryToExpressionCompletion = PrimaryToExpressionCompletion positionalTupleCompletion = PositionalTupleExpressionListCompletion + ) + | '=>' indexedNameCompletion = IndexedNamedExpressionListCompletion + ) + | positionalTupleList = PositionalTupleExpressionList)? ')' ; + +IndexedNamedExpressionListCompletion : + expression = Expression ( ',' indexedNameExpression += IndexedNamedExpression )* ; + +IndexedNamedExpression : + name = Name ( index = Index )? '=>' expression = Expression ; + +/* CLASS EXTENT EXPRESSIONS */ +ClassExtentExpressionCompletion : + {ClassExtentExpressionCompletion}'allInstances' '(' ')' ; + +/* SEQUENCE CONSTRUCTION EXPRESSIONS */ +SequenceAnyExpression : + {SequenceAnyExpression}'any' completion = SequenceConstructionExpressionCompletion + | {SequenceAnyExpression}'null' ; + +SequenceConstructionExpressionCompletion : + {SequenceConstructionExpressionCompletion}( multiplicityIndicator = MultiplicityIndicator )? '{'( sequenceElements = SequenceElements )? '}' ; + +MultiplicityIndicator : + '[' ']' ; + +SequenceElements : + expression = Expression ( '::' expressionCompletion = Expression | sequenceCompletion = SequenceElementListCompletion ) + | initializationExpression = SequenceInitializationExpression sequenceCompletion = SequenceElementListCompletion ; + +SequenceElementListCompletion : + {SequenceElementListCompletion}( ',' sequenceElement += SequenceElement )* ( ',' )? ; + +SequenceElement : + Expression | SequenceInitializationExpression ; + +SequenceInitializationExpression : + ( 'new' )? '{' SequenceElements '}' ; + +/* SEQUENCE ACCESS EXPRESSIONS */ +Index : + '[' Expression ']' ; + +/* SEQUENCE OPERATION, REDUCTION AND EXPANSION EXPRESSIONS */ +SequenceOperationOrReductionOrExpansion : + '->' + ( qualifiedName = QualifiedName tuple = Tuple | 'reduce' ( 'ordered' )? qualifiedName = QualifiedName + | expansionOperator = ExpansionOperator name = Name '(' expression = Expression ')') ; + +enum ExpansionOperator : + SELECT = 'select' | + COLLECT = 'collect' | + REJECT = 'reject' | + ITERATE = 'iterate' | + FORALL = 'forAll' | + EXISTS = 'exists'| + ONE = 'one' ; + +/* INCREMENT OR DECREMENT EXPRESSIONS */ +PostfixExpressionCompletion : + primaryCompletion = PrimaryExpressionCompletion ( postfixOperation = PostfixOperation )? ; + +PostfixOperation : + operator = AffixOperator ; + +PrefixExpression : + operator = AffixOperator expression = PrimaryExpression ; + +enum AffixOperator : + INCR = '++' | + DECR = '--' ; + +/* UNARY EXPRESSIONS */ +UnaryExpression : + PostfixOrCastExpression | NonPostfixNonCastUnaryExpression ; + +PostfixOrCastExpression : + NonNamePostfixOrCastExpression | NameOrPrimaryExpressionAlt ; + +// ADDED for implem of PostfixOrCastExpression +NameOrPrimaryExpressionAlt : + nameOrPrimary = NameOrPrimaryExpression completion = PostfixExpressionCompletion ; +///////////////////////////////////////////////////////// + +NonNameUnaryExpression : + NonNamePostfixOrCastExpression | NonPostfixNonCastUnaryExpression ; + +NonNamePostfixOrCastExpression : + '(' ( 'any' '(' castCompletion1 = CastCompletion | qualifiedName = PotentiallyAmbiguousQualifiedName + ( ')' castCompletion2 = CastCompletion + | nameToExpressionCompletion = NameToExpressionCompletion ')' postfixExpressionCompletion = PostfixExpressionCompletion + ) + | nonNameExpression = NonNameExpression ')' postfixExpressionCompletion = PostfixExpressionCompletion) + | baseExpression = BaseExpression postfixExpressionCompletion = PostfixExpressionCompletion ; + +NonPostfixNonCastUnaryExpression : + PrefixExpression + | NumericUnaryExpression + | BooleanNegationExpression + | BitStringComplementExpression + | IsolationExpression ; + +BooleanNegationExpression : + '!' unaryExpression = UnaryExpression ; + +BitStringComplementExpression : + '~' unaryExpression = UnaryExpression ; + +NumericUnaryExpression : + operator = NumericUnaryOperator unaryExpression = UnaryExpression ; + +enum NumericUnaryOperator : + PLUS ='+' | + MINUS = '-' ; + +IsolationExpression : + '$' unaryExpression = UnaryExpression ; + +//CastExpression : +// '(' typeName = TypeName ')' castCompletion = CastCompletion ; + +CastCompletion : + PostfixOrCastExpression + | BooleanNegationExpression + | BitStringComplementExpression + | IsolationExpression ; + +/* ARITHMETIC EXPRESSIONS */ +MultiplicativeExpression : + unaryExpression = UnaryExpression completion = MultiplicativeExpressionCompletion ; + +MultiplicativeExpressionCompletion : + {MultiplicativeExpressionCompletion}( multiplicativeOperator += MultiplicativeOperator unaryExpression += UnaryExpression )* ; + +enum MultiplicativeOperator : + STAR = '*' | + DIV = '/' | + MOD = '%' ; + +AdditiveExpression : + unaryExpression = UnaryExpression completion = AdditiveExpressionCompletion ; + +AdditiveExpressionCompletion : + MultiplicativeExpressionCompletion + ( {AdditiveExpressionCompletion.firstCompletion = current} additiveOperator += AdditiveOperator multiplicativeExpression += MultiplicativeExpression + ( additiveOperator += AdditiveOperator multiplicativeExpression += MultiplicativeExpression)*)? ; + +enum AdditiveOperator : + PLUS = '+' | + MINUS = '-' ; +/* SHIFT EXPRESSIONS */ +ShiftExpression : + unaryExpression = UnaryExpression completion = ShiftExpressionCompletion ; + +ShiftExpressionCompletion : + AdditiveExpressionCompletion + ({ShiftExpressionCompletion.firstCompletion = current} shiftOperator += ShiftOperator additiveExpression += AdditiveExpression + ( shiftOperator += ShiftOperator additiveExpression += AdditiveExpression )*)? ; + +enum ShiftOperator : + LSHIFT = '<<' | + RSHIFT = '>>' | + URSHIFT = '>>>' ; + +/* RELATIONAL EXPRESSIONS */ +RelationalExpression : + unaryExpression = UnaryExpression completion = RelationalExpressionCompletion ; + +RelationalExpressionCompletion : + ShiftExpressionCompletion + ({RelationalExpressionCompletion.firstCompletion = current}relationalOperator = RelationalOperator shiftExpression = ShiftExpression )? ; + +enum RelationalOperator : + LT = '<' | + GT = '>' | + LE = '<=' | + GE = '>=' ; + +/* CLASSIFICATION EXPRESSIONS */ +ClassificationExpression : + RelationalExpression ({ClassificationExpression.expression = current} completion = ClassificationExpressionCompletion)? ; + //unaryExpression = UnaryExpression completion = ClassificationExpressionCompletion ; + +ClassificationExpressionCompletion : + RelationalExpressionCompletion + ({ClassificationExpressionCompletion.firstCompletion=current} classificationOperator = ClassificationOperator qualifiedName = QualifiedName )? ; + +enum ClassificationOperator : + INSTANCEOF = 'instanceof' | + HASTYPE = 'hastype' ; +/* EQUALITY EXPRESSIONS */ +EqualityExpression : + unaryExpression = UnaryExpression completion = ClassificationExpressionCompletion ; + +EqualityExpressionCompletion : + ClassificationExpressionCompletion + ( {EqualityExpressionCompletion.firstCompletion=current} equalityOperator += EqualityOperator classificationExpression += ClassificationExpression + ( equalityOperator += EqualityOperator classificationExpression += ClassificationExpression)*)? ; + +enum EqualityOperator : + EQ = '==' | + NE = '!=' ; +/* LOGICAL EXPRESSIONS */ +AndExpression : + unaryExpression = UnaryExpression completion = AndExpressionCompletion ; + +AndExpressionCompletion : + EqualityExpressionCompletion + ( {AndExpressionCompletion.firstCompletion = current}'&' equalityExpression += EqualityExpression + ( '&' equalityExpression += EqualityExpression )*)? ; + +ExclusiveOrExpression : + unaryExpression = UnaryExpression completion = ExclusiveOrExpressionCompletion ; + +ExclusiveOrExpressionCompletion : + AndExpressionCompletion + ({ExclusiveOrExpressionCompletion.firstExpression=current} '^' andExpression += AndExpression + ( '^' andExpression += AndExpression )*)? ; + +InclusiveOrExpression : + unaryExpression = UnaryExpression completion = InclusiveOrExpressionCompletion ; + +InclusiveOrExpressionCompletion : + ExclusiveOrExpressionCompletion + ({InclusiveOrExpressionCompletion.firstCompletion=current} '|' exclusiveOrExpression += ExclusiveOrExpression + ( '|' exclusiveOrExpression += ExclusiveOrExpression )*)? ; + +/* CONDITIONAL LOGICAL EXPRESSIONS */ +ConditionalAndExpression : + unaryExpression = UnaryExpression completion = ConditionalAndExpressionCompletion ; + +ConditionalAndExpressionCompletion : + InclusiveOrExpressionCompletion + ({ConditionalAndExpressionCompletion.firstCompletion = current} '&&' inclusiveOrExpression += InclusiveOrExpression + ( '&&' inclusiveOrExpression += InclusiveOrExpression )*)? ; + +ConditionalOrExpression : + unaryExpression = UnaryExpression completion = ConditionalOrExpressionCompletion ; + +ConditionalOrExpressionCompletion : + ConditionalAndExpressionCompletion + ({ConditionalOrExpressionCompletion.firstCompletion = current} '||' conditionalAndExpression += ConditionalAndExpression + ( '||' conditionalAndExpression += ConditionalAndExpression )*)? ; + +/* CONDITIONAL-TEST EXPRESSIONS */ +//ConditionalExpression : +// unaryExpression = UnaryExpression completion = ConditionalExpressionCompletion ; + +ConditionalExpressionCompletion : + ConditionalOrExpressionCompletion + ({ConditionalExpressionCompletion.firstCompletion = current} '?' expression1 = ConditionalOrExpression ':' expression2 = ConditionalOrExpression )? ; +/* ASSIGNMENT EXPRESSIONS */ +AssignmentExpressionCompletion : + operator = AssignmentOperator expression = Expression ; + +enum AssignmentOperator : + ASSIGN = '=' + | PLUSASSIGN = '+=' + | MINUSASSIGN = '-=' + | STARASSIGN = '*=' + | SLASHASSIGN = '/=' + | REMASSIGN = '%=' + | ANSASSIGN = '&=' + | ORASSIGN = '|=' + | XORASSIGN = '^=' + | LSHIFTASSIGN = '<<=' + | RSHIFTASSIGN = '>>=' + | URSHIFTASSIGN = '>>>=' ; + + +/**************** +* Terminals +*****************/ + +//terminal DOUBLE_COLON : '::' ; + +terminal ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* | ('\'' -> '\'') ; +terminal STRING : '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'"'|"'"|'\\') | !('\\'|'"') )* '"' ; +//terminal IDENTIFIER : ID ; +//terminal IDENTIFIER : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* | ('\'' -> '\'') ; + +//terminal DOCUMENTATION_COMMENT : '/*' -> '*/' ; + +//terminal ML_COMMENT : '/°' -> '°/'; +//terminal SL_COMMENT : '°°' !('\n'|'\r')* ('\r'? '\n')?; + +//terminal WS : (' '|'\t'|'\r'|'\n')+;
\ No newline at end of file diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/GenerateAlf.mwe2 b/extraplugins/alf09/src/org/eclipse/papyrus/alf/GenerateAlf.mwe2 new file mode 100644 index 00000000000..fd626100672 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/GenerateAlf.mwe2 @@ -0,0 +1,103 @@ +module org.eclipse.papyrus.alf.Alf + +import org.eclipse.emf.mwe.utils.* +import org.eclipse.xtext.generator.* +import org.eclipse.xtext.ui.generator.* + +var grammarURI = "classpath:/org/eclipse/papyrus/alf/Alf.xtext" +var file.extensions = "alf" +var projectName = "org.eclipse.papyrus.alf" +var runtimeProject = "../${projectName}" + +Workflow { + bean = StandaloneSetup { + platformUri = "${runtimeProject}/.." + } + + component = DirectoryCleaner { + directory = "${runtimeProject}/src-gen" + } + + component = DirectoryCleaner { + directory = "${runtimeProject}.ui/src-gen" + } + + component = Generator { + pathRtProject = runtimeProject + pathUiProject = "${runtimeProject}.ui" + projectNameRt = projectName + projectNameUi = "${projectName}.ui" + language = { + uri = grammarURI + fileExtensions = file.extensions + + // Java API to access grammar elements (required by several other fragments) + fragment = grammarAccess.GrammarAccessFragment {} + + // generates Java API for the generated EPackages + fragment = ecore.EcoreGeneratorFragment { + // referencedGenModels = "uri to genmodel, uri to next genmodel" + } + + // the serialization component + fragment = parseTreeConstructor.ParseTreeConstructorFragment {} + + // a custom ResourceFactory for use with EMF + fragment = resourceFactory.ResourceFactoryFragment { + fileExtensions = file.extensions + } + + // The antlr parser generator fragment. + fragment = parser.antlr.XtextAntlrGeneratorFragment { + //options = { + // backtrack = true + //} + } + + // java-based API for validation + fragment = validation.JavaValidatorFragment { + composedCheck = "org.eclipse.xtext.validation.ImportUriValidator" + // composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" + // registerForImportedPackages = true + } + + // scoping and exporting API + fragment = scoping.ImportURIScopingFragment {} + fragment = exporting.SimpleNamesFragment {} + + // scoping and exporting API + //fragment = scoping.ImportNamespacesScopingFragment {} + //fragment = exporting.QualifiedNamesFragment {} + //fragment = builder.BuilderIntegrationFragment {} + + // formatter API + fragment = formatting.FormatterFragment {} + + // labeling API + fragment = labeling.LabelProviderFragment {} + + // outline API + fragment = outline.OutlineTreeProviderFragment {} + fragment = outline.QuickOutlineFragment {} + + // quickfix API + fragment = quickfix.QuickfixProviderFragment {} + + // content assist API + fragment = contentAssist.JavaBasedContentAssistFragment {} + + // generates a more lightweight Antlr parser and lexer tailored for content assist + fragment = parser.antlr.XtextAntlrUiGeneratorFragment { + //options = { + // backtrack = true + //} + } + + // project wizard (optional) + // fragment = projectWizard.SimpleProjectWizardFragment { + // generatorProjectName = "${projectName}.generator" + // modelFileExtension = file.extensions + // } + } + } +} diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/formatting/AlfFormatter.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/formatting/AlfFormatter.java new file mode 100644 index 00000000000..3add6fb48e7 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/formatting/AlfFormatter.java @@ -0,0 +1,37 @@ +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.alf.formatting; + +import org.eclipse.xtext.formatting.impl.AbstractDeclarativeFormatter; +import org.eclipse.xtext.formatting.impl.FormattingConfig; + +/** + * This class contains custom formatting description. + * + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting + * on how and when to use it + * + * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example + */ +public class AlfFormatter extends AbstractDeclarativeFormatter { + + @Override + protected void configureFormatting(FormattingConfig c) { +// It's usually a good idea to activate the following three statements. +// They will add and preserve newlines around comments +// c.setLinewrap(0, 1, 2).before(getGrammarAccess().getSL_COMMENTRule()); +// c.setLinewrap(0, 1, 2).before(getGrammarAccess().getML_COMMENTRule()); +// c.setLinewrap(0, 1, 1).after(getGrammarAccess().getML_COMMENTRule()); + } +} diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfPartialScope.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfPartialScope.java new file mode 100644 index 00000000000..32cddeaaec0 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfPartialScope.java @@ -0,0 +1,76 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.scoping;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+
+public class AlfPartialScope {
+
+ private List<List<EObject>> nestedScopes ;
+ private IGetNameStrategy nameStrategy ;
+ private IBuildScopeStrategy buildScopeStrategy ;
+
+ public AlfPartialScope(IGetNameStrategy nameStrategy, IBuildScopeStrategy buildScopeStrategy, EObject contextElement) {
+ this.nameStrategy = nameStrategy ;
+ this.buildScopeStrategy = buildScopeStrategy ;
+ nestedScopes = buildScopeStrategy.buildScope(contextElement) ;
+ }
+
+ public String getElementName(EObject eObject) {
+ return nameStrategy.getName(eObject) ;
+ }
+
+ public void buildScope(EObject contextElement) {
+ nestedScopes = buildScopeStrategy.buildScope(contextElement) ;
+ }
+
+ public List<EObject> resolveByName(String elemName) {
+ List<EObject> resolvedElements = new ArrayList<EObject>() ;
+ Iterator<List<EObject>> nestedScopesIterator = nestedScopes.iterator() ;
+ String normalizedElementName = elemName.startsWith("'") ?
+ elemName.substring(1, elemName.length()-1) : // removes first and last '
+ elemName ;
+ while (nestedScopesIterator.hasNext() && resolvedElements.isEmpty()) {
+ for (EObject elem : nestedScopesIterator.next()) {
+ if (getElementName(elem).equals(normalizedElementName))
+ resolvedElements.add(elem) ;
+ }
+ }
+ return resolvedElements ;
+ }
+
+ public List<List<EObject>> getScopeDetails() {
+ return nestedScopes ;
+ }
+
+ public int getScopingLevel(EObject element) {
+ for (int i = 0 ; i<nestedScopes.size() ; i++) {
+ if (nestedScopes.get(i).contains(element))
+ return i ;
+ }
+ return -1 ;
+ }
+
+ public interface IGetNameStrategy {
+ public String getName(EObject element) ;
+ }
+
+ public interface IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java new file mode 100644 index 00000000000..cbbb2d9ace9 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfScopeProvider.java @@ -0,0 +1,27 @@ +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.alf.scoping; + +import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider; + +/** + * This class contains custom scoping description. + * + * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping + * on how and when to use it + * + */ +public class AlfScopeProvider extends AbstractDeclarativeScopeProvider { + public static AlfScopingTool scopingTool ; +} diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java new file mode 100644 index 00000000000..4f909b79725 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/scoping/AlfScopingTool.java @@ -0,0 +1,722 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.scoping;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.AcceptClause;
+import org.eclipse.papyrus.alf.alf.AcceptStatement;
+import org.eclipse.papyrus.alf.alf.DocumentedStatement;
+import org.eclipse.papyrus.alf.alf.InvocationOrAssignementOrDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
+import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
+import org.eclipse.papyrus.alf.alf.Statement;
+import org.eclipse.papyrus.alf.validation.AlfJavaValidator;
+import org.eclipse.papyrus.alf.validation.typing.TypeExpression;
+import org.eclipse.papyrus.alf.validation.typing.TypeUtils;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.EnumerationLiteral;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Namespace;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageImport;
+import org.eclipse.uml2.uml.PackageableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Reception;
+import org.eclipse.uml2.uml.Signal;
+import org.eclipse.uml2.uml.VisibilityKind;
+
+public abstract class AlfScopingTool {
+
+ protected static List<EObject> removeDuplicateClassifiers(List<EObject> list) {
+ List<EObject> intermediateFilteredList = new ArrayList<EObject>() ;
+
+ HashMap<String, Classifier> classifiers = new HashMap<String, Classifier>() ;
+ HashMap<String, Classifier> elementImports = new HashMap<String, Classifier>() ;
+ for (EObject o : list) {
+ if (o instanceof Classifier) {
+ Classifier c = (Classifier) o ;
+ if (classifiers.get(c.getQualifiedName()) == null) {
+ classifiers.put(c.getQualifiedName(), c) ;
+ intermediateFilteredList.add(c) ;
+ }
+ // else => nothing to be done, this is a duplicate
+ }
+ else if (o instanceof ElementImport) {
+ ElementImport e = (ElementImport)o ;
+ Classifier c = (Classifier)e.getImportedElement() ;
+ if (elementImports.get(e.getAlias()) == null) {
+ elementImports.put(e.getAlias(), c) ;
+ intermediateFilteredList.add(e) ;
+ }
+ else {// need to check if element import aliases the same thing.
+ Classifier alreadyInTheList = elementImports.get(e.getAlias()) ;
+ if (! alreadyInTheList.getQualifiedName().equals(c.getQualifiedName())) {
+ // The model is ill-formed, and there's no need to filter
+ intermediateFilteredList.add(e) ;
+ }
+ // else => nothing to be done, this is a duplicate
+ }
+ }
+ }
+
+ // needs to make a second pass on the filtered list, to remove cases where aliases and names are the same, and represent the same element
+ List<EObject> filteredList = new ArrayList<EObject>() ;
+ for (int i = 0 ; i < intermediateFilteredList.size() ; i++) {
+ String classifierName = (intermediateFilteredList.get(i) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(i)).getName() :
+ ((ElementImport)intermediateFilteredList.get(i)).getAlias() ;
+ String classifierQualifiedName = (intermediateFilteredList.get(i) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(i)).getQualifiedName() :
+ ((Classifier)((ElementImport)intermediateFilteredList.get(i)).getImportedElement()).getQualifiedName() ;
+ boolean duplicateFound = false ;
+ for (int j = i + 1 ; j < intermediateFilteredList.size() && !duplicateFound ; j++) {
+ String cddDuplicateClassifierName = (intermediateFilteredList.get(j) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(j)).getName() :
+ ((ElementImport)intermediateFilteredList.get(j)).getAlias() ;
+ if (cddDuplicateClassifierName.equals(classifierName)) {
+ String cddDuplicateClassifierQualifiedName = (intermediateFilteredList.get(j) instanceof Classifier) ?
+ ((Classifier)intermediateFilteredList.get(j)).getQualifiedName() :
+ ((Classifier)((ElementImport)intermediateFilteredList.get(j)).getImportedElement()).getQualifiedName() ;
+ if (cddDuplicateClassifierQualifiedName.equals(classifierQualifiedName)) {
+ duplicateFound = true ;
+ }
+ }
+ }
+ if (!duplicateFound)
+ filteredList.add(intermediateFilteredList.get(i)) ;
+ }
+
+ return filteredList ;
+ }
+
+ public abstract AlfPartialScope getVisibleVariablesOrParametersOrProperties(EObject context) ;
+
+
+ public AlfPartialScope getVisibleOperationsOrBehaviors(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new OperationAndBehaviorNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new OperationAndBehaviorBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public AlfPartialScope getVisibleBehaviors(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new BehaviorsNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new BehaviorsBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public AlfPartialScope getVisibleClassifiers(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new ClassifiersNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new ClassifiersBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public AlfPartialScope getVisiblePackages(EObject context) {
+ if (context instanceof Package) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new PackageNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new PackagesBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+ AlfPartialScope.IGetNameStrategy nameStrategy = new PackageNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new PackagesBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+ public boolean isAReturnStatementExpected(EObject context) {
+ return false ;
+ }
+
+ public TypeExpression getExpectedReturnType(EObject context) {
+ return null;
+ }
+
+ public AlfPartialScope getVisibleSignalReceptions(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new ReceptionsNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new ReceptionsBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context);
+ }
+
+ /*
+ * Strategies for operations
+ */
+ protected class OperationAndBehaviorNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Operation)
+ return ((Operation)element).getName();
+ else if (element instanceof Behavior)
+ return ((Behavior)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)element ;
+ if (eImport.getAlias() != null)
+ return eImport.getAlias() ;
+ else
+ return ((Behavior)eImport.getImportedElement()).getName() ;
+ }
+ else if (element instanceof Reception) {
+ return ((Reception)element).getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class OperationAndBehaviorBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // in the case where the context element is a Package or an ElementImport for a package, the scope can only contain behaviors
+ Package potentialContextPackage = null ;
+ if (contextElement instanceof Package) {
+ potentialContextPackage = (Package)contextElement ;
+ }
+ else if (contextElement instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)contextElement ;
+ if (eImport.getImportedElement() instanceof Package)
+ potentialContextPackage = (Package)eImport.getImportedElement() ;
+ }
+ if (potentialContextPackage != null) {
+ AlfPartialScope behaviorScope = AlfScopeProvider.scopingTool.getVisibleBehaviors(contextElement) ;
+ for (List<EObject> scope : behaviorScope.getScopeDetails()) {
+ nestedScopes.add(scope) ;
+ }
+ return nestedScopes ;
+ }
+
+ // At this point, we have identified that the context element is not a package.
+
+ // First scoping levels concern operations
+ // retrieves the contextClassier (i.e. the owner of the contextOperation, or contextElement)
+ Classifier contextClassifier ;
+ if (contextElement instanceof Classifier) {
+ contextClassifier = (Classifier)contextElement ;
+ }
+ else if (contextElement instanceof ElementImport && ((ElementImport)contextElement).getImportedElement() instanceof Classifier) {
+ contextClassifier = (Classifier) ((ElementImport)contextElement).getImportedElement() ;
+ }
+ else {
+ contextClassifier = AlfJavaValidator.getContextClassifier() ;
+ }
+
+ // add all the operations owned by the context classifier at the first scoping level
+ nestedList.addAll(contextClassifier.getOperations()) ;
+ // adds also receptions
+ if (contextClassifier instanceof org.eclipse.uml2.uml.Class) {
+ nestedList.addAll(((Class)contextClassifier).getOwnedReceptions()) ;
+ }
+
+ nestedScopes.add(nestedList) ;
+ // then builds other scoping levels based on context classifier inheritance hierarchy
+ List<Classifier> currentGenerals = new ArrayList<Classifier>() ;
+ currentGenerals.addAll(contextClassifier.getGenerals()) ;
+ List<Classifier> nextGenerals ;
+ while (!currentGenerals.isEmpty()) {
+ nextGenerals = new ArrayList<Classifier>() ;
+ nestedList = new ArrayList<EObject>() ;
+ for (Classifier general : currentGenerals) {
+ nextGenerals.addAll(general.getGenerals()) ;
+ for (Operation o : general.getOperations())
+ nestedList.add(o) ;
+ if (general instanceof Class) {
+ for (Reception r : ((Class)general).getOwnedReceptions()) {
+ nestedList.add(r) ;
+ }
+ }
+ }
+ nestedScopes.add(nestedList) ;
+ currentGenerals = nextGenerals ;
+ }
+
+ // finally feeds last scoping levels with behaviors (only if contextElement is not a Class)
+ if (! ((contextElement instanceof Classifier) ||
+ ((contextElement instanceof ElementImport &&
+ ((ElementImport)contextElement).getImportedElement() instanceof Classifier)))) {
+
+ AlfPartialScope behaviorScope = AlfScopeProvider.scopingTool.getVisibleBehaviors(contextElement) ;
+
+ for (List<EObject> scope : behaviorScope.getScopeDetails()) {
+ nestedScopes.add(scope) ;
+ }
+ }
+
+ return nestedScopes ;
+ }
+ }
+
+ /*
+ * Strategies for Receptions
+ */
+ protected class ReceptionsNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Signal)
+ return ((Signal)element).getName();
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class ReceptionsBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // retrieves the owner of the contextOperation
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+ if (! (contextClassifier instanceof org.eclipse.uml2.uml.Class)) {
+ nestedScopes.add(nestedList) ;
+ return nestedScopes ;
+ }
+
+ // add all the signals for which a Reception is defined
+ for (org.eclipse.uml2.uml.Feature f : contextClassifier.allFeatures()) {
+ if (f instanceof Reception)
+ if (((Reception)f).getSignal() != null)
+ nestedList.add(((Reception)f).getSignal()) ;
+ }
+
+ nestedScopes.add(nestedList) ;
+
+ return nestedScopes ;
+ }
+ }
+
+ /*
+ * Strategies for Variables, Parameters and Properties
+ */
+ protected class VariableOrParameterOrPropertyNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Property)
+ return ((Property)element).getName();
+ else if (element instanceof LocalNameDeclarationStatement){
+ return ((LocalNameDeclarationStatement)element).getVarName() ;
+ }
+ else if (element instanceof InvocationOrAssignementOrDeclarationStatement) {
+ InvocationOrAssignementOrDeclarationStatement statement = (InvocationOrAssignementOrDeclarationStatement)element ;
+ return statement.getVariableDeclarationCompletion() != null ?
+ statement.getVariableDeclarationCompletion().getVariableName() :
+ "" ;
+ }
+ else if (element instanceof LoopVariableDefinition) {
+ return ((LoopVariableDefinition)element).getName() ;
+ }
+ else if (element instanceof AcceptClause) {
+ return ((AcceptClause)element).getName() ;
+ }
+ else if (element instanceof AcceptStatement) {
+ return ((AcceptStatement)element).getClause().getName() ;
+ }
+ else if (element instanceof SequenceExpansionExpression) {
+ SequenceExpansionExpression expression = (SequenceExpansionExpression)element ;
+ return expression.getName() != null ?
+ expression.getName() :
+ "" ;
+ }
+ return "unexpected kind ..." ;
+ }
+ }
+
+ protected abstract class VariableOrPropertyOrParameterBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public abstract List<List<EObject>> buildScope(EObject contextElement) ;
+
+ public boolean containsALocalNameDeclaration(DocumentedStatement previousDocumentStatement) {
+ Statement statement = previousDocumentStatement.getStatement() ;
+ if (statement instanceof LocalNameDeclarationStatement)
+ return true ;
+ if (statement instanceof InvocationOrAssignementOrDeclarationStatement) {
+ //TODO : handle cases with implicit declarations, e.g., v = 14 ; // v is a variable of type Integer
+ InvocationOrAssignementOrDeclarationStatement cddDclStatement = (InvocationOrAssignementOrDeclarationStatement)statement;
+ if (cddDclStatement.getVariableDeclarationCompletion() != null) {
+ return true ;
+ }
+ }
+ if (statement instanceof AcceptStatement) {
+ AcceptStatement cddDclStatement = (AcceptStatement)statement ;
+ if (cddDclStatement.getSimpleAccept() != null && cddDclStatement.getClause().getName() != null)
+ return true ;
+ }
+ return false;
+ }
+
+ }
+
+ /*
+ * Strategies for Classifiers
+ */
+ protected class ClassifiersNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Classifier)
+ return ((Classifier)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport imported = (ElementImport)element ;
+ return imported.getAlias() != null ? imported.getAlias() : ((Classifier)imported.getImportedElement()).getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class ClassifiersBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // first checks if contextElement represents a Package. In this case, builds a scope containing all classifiers visible from this package
+ Package potentialContextPackage = null ;
+ if (contextElement instanceof Package)
+ potentialContextPackage = (Package)contextElement ;
+ else if (contextElement instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)contextElement ;
+ if (eImport.getImportedElement() instanceof Package)
+ potentialContextPackage = (Package)eImport.getImportedElement() ;
+ }
+ if (potentialContextPackage != null) {
+ List<EObject> importedClassifiers = processPublicallyImportedClassifiers(potentialContextPackage) ;
+ importedClassifiers = removeDuplicateClassifiers(importedClassifiers) ;
+ nestedScopes.add(importedClassifiers) ;
+ return nestedScopes ;
+ }
+
+ // retrieves the owner of the contextOperation
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+
+ // add the context classifier at the first scoping level
+ nestedList.add(contextClassifier) ;
+ // retrieves all package imports, and add all classifiers available at the root of this package
+ for (PackageImport i : contextClassifier.getPackageImports()) {
+ Package importedPackage = i.getImportedPackage() ;
+ nestedList.addAll(processPublicallyImportedClassifiers(importedPackage)) ;
+ }
+ // retrieves all element imports. For those which concern a Classifier, either add the classifier if no alias is defined, or the element import if an alias is defined
+ for (ElementImport i : contextClassifier.getElementImports()) {
+ PackageableElement e = i.getImportedElement() ;
+ if (e instanceof Classifier) {
+ if (i.getAlias() != null)
+ nestedList.add(i) ;
+ else
+ nestedList.add(e) ;
+ }
+ }
+ nestedList = removeDuplicateClassifiers(nestedList) ;
+ nestedScopes.add(nestedList) ;
+
+ // Then process the implicit import of alf library
+ nestedList = new ArrayList<EObject>() ;
+ if (AlfJavaValidator.getAlfStandardLibrary() != null) {
+ List<EObject> importedClassifiers = processPublicallyImportedClassifiers(AlfJavaValidator.getAlfStandardLibrary()) ;
+
+ importedClassifiers.add(TypeUtils._Collection.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Set.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Bag.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Queue.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._OrderedSet.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._List.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Deque.extractActualType()) ;
+ importedClassifiers.add(TypeUtils._Map.extractActualType()) ;
+ //importedClassifiers.add(TypeUtils._Entry.extractActualType()) ;
+
+ nestedList.addAll(removeDuplicateClassifiers(importedClassifiers)) ;
+ nestedScopes.add(nestedList) ;
+ }
+
+ // Then process all classifiers at the same namespace level than the context classifier
+ nestedList = new ArrayList<EObject>() ;
+ Namespace namespaceOfContextClassifier = contextClassifier.getNamespace() ;
+ for (Element e : namespaceOfContextClassifier.getOwnedElements()) {
+ if (e instanceof Classifier && e != contextClassifier)
+ nestedList.add(e) ;
+ }
+ nestedScopes.add(nestedList) ;
+
+ return nestedScopes ;
+ }
+
+ private List<EObject> processPublicallyImportedClassifiers (Package p){
+ List<EObject> importedClassifiers = new ArrayList<EObject>() ;
+ for (NamedElement n : p.getOwnedMembers()) {
+ if (n instanceof Classifier)
+ if (((Classifier)n).getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+
+ importedClassifiers.add(n) ;
+ }
+ }
+ for (ElementImport eImport : p.getElementImports()) {
+ if (eImport.getVisibility()!= VisibilityKind.PRIVATE_LITERAL) {
+ PackageableElement element = eImport.getImportedElement() ;
+ if (element instanceof Classifier) {
+
+ if (eImport.getAlias() != null) {
+ importedClassifiers.add(eImport) ;
+ }
+ else {
+ importedClassifiers.add(element) ;
+ }
+
+ }
+ }
+ }
+ for (PackageImport pImport : p.getPackageImports()) {
+ if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+ importedClassifiers.addAll(processPublicallyImportedClassifiers(pImport.getImportedPackage())) ;
+ }
+ }
+ return importedClassifiers ;
+ }
+ }
+
+ /*
+ * Strategies for Packages
+ */
+ protected class PackageNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Namespace)
+ return ((Namespace)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)element ;
+ return eImport.getAlias() != null ? eImport.getAlias() : eImport.getImportedElement().getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ }
+
+ protected class PackagesBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ if (contextElement instanceof Package) { // if the context element is a package, returns the scope related to this package.
+ nestedScopes.add(processPublicallyImportedPackages((Package)contextElement)) ;
+ return nestedScopes ;
+ }
+
+ Package root = (Package)AlfJavaValidator.getModel() ;
+
+ // first process packages directly imported by the context classifier (either package import or element import)
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+
+ nestedList.addAll(processPublicallyImportedPackages(contextClassifier)) ;
+ nestedScopes.add(nestedList) ;
+
+ // Then process the implicit import of alf library
+ nestedList = new ArrayList<EObject>() ;
+ if (AlfJavaValidator.getAlfStandardLibrary() != null) {
+ nestedList.add(AlfJavaValidator.getAlfStandardLibrary()) ;
+ nestedList.addAll(processPublicallyImportedPackages(AlfJavaValidator.getAlfStandardLibrary())) ;
+ nestedScopes.add(nestedList) ;
+ }
+
+ // finally processes the root package
+ nestedList = new ArrayList<EObject>() ;
+ nestedList.add(root) ;
+ nestedScopes.add(nestedList) ;
+
+ return nestedScopes;
+ }
+
+ protected List<EObject> processPublicallyImportedPackages (Namespace namespace) {
+ List<EObject> importedPackages = new ArrayList<EObject>() ;
+
+ for (NamedElement ownedMember : namespace.getOwnedMembers()) {
+ if (ownedMember.getVisibility() != VisibilityKind.PRIVATE_LITERAL && ownedMember instanceof Package)
+ importedPackages.add(ownedMember) ;
+ }
+ for (ElementImport eImport : namespace.getElementImports()) {
+ if (eImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL ) {
+ PackageableElement importedElement = eImport.getImportedElement() ;
+ if (importedElement instanceof Package) {
+ if (eImport.getAlias() != null)
+ importedPackages.add(eImport) ;
+ else
+ importedPackages.add(importedElement) ;
+ }
+ }
+ }
+ for (PackageImport pImport : namespace.getPackageImports()) {
+ if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+ importedPackages.addAll(processPublicallyImportedPackages(pImport.getImportedPackage())) ;
+ }
+ }
+
+ return importedPackages ;
+ }
+ }
+
+
+ /*
+ * Strategies for Behaviors
+ */
+
+ protected class BehaviorsNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof Behavior)
+ return ((Behavior)element).getName() ;
+ else if (element instanceof ElementImport) {
+ ElementImport imported = (ElementImport)element ;
+ return imported.getAlias() != null ? imported.getAlias() : ((Behavior)imported.getImportedElement()).getName() ;
+ }
+ else
+ return "Unexpected element kind..." ;
+ }
+ };
+
+ protected class BehaviorsBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ // first checks if contextElement represents a Package. In this case, builds a scope containing all behaviors visible from this package
+ Package potentialContextPackage = null ;
+ if (contextElement instanceof Package)
+ potentialContextPackage = (Package)contextElement ;
+ else if (contextElement instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)contextElement ;
+ if (eImport.getImportedElement() instanceof Package)
+ potentialContextPackage = (Package)eImport.getImportedElement() ;
+ }
+ if (potentialContextPackage != null) {
+ nestedScopes.add(processPublicallyImportedBehaviors(potentialContextPackage)) ;
+ return nestedScopes ;
+ }
+
+ // retrieves the contextOperation (i.e., the operation edited by the current editor)
+ // retrieves the owner of the contextOperation
+ Classifier contextClassifier = AlfJavaValidator.getContextClassifier() ;
+
+ // retrieves all package imports, and add all behaviors available at the root of this package
+ for (PackageImport i : contextClassifier.getPackageImports()) {
+ Package importedPackage = i.getImportedPackage() ;
+ nestedList.addAll(processPublicallyImportedBehaviors(importedPackage)) ;
+ }
+ // retrieves all element imports. For those which concern a Behavior, either add the behavior if no alias is defined, or the element import if an alias is defined
+ for (ElementImport i : contextClassifier.getElementImports()) {
+ PackageableElement e = i.getImportedElement() ;
+ if (e instanceof Classifier) {
+ if (i.getAlias() != null)
+ nestedList.add(i) ;
+ else
+ nestedList.add(e) ;
+ }
+ }
+ nestedList = removeDuplicateClassifiers(nestedList) ;
+ nestedScopes.add(nestedList) ;
+
+ // Then process the implicit import of alf library
+ nestedList = new ArrayList<EObject>() ;
+ if (AlfJavaValidator.getAlfStandardLibrary() != null) {
+ List<EObject> importedClassifiers = processPublicallyImportedBehaviors(AlfJavaValidator.getAlfStandardLibrary()) ;
+ importedClassifiers = removeDuplicateClassifiers(importedClassifiers) ;
+ nestedList.addAll(importedClassifiers) ;
+ nestedScopes.add(nestedList) ;
+ }
+
+ return nestedScopes ;
+ }
+
+ private List<EObject> processPublicallyImportedBehaviors (Package p){
+ List<EObject> importedBehaviors = new ArrayList<EObject>() ;
+ for (NamedElement n : p.getOwnedMembers()) {
+ if (n instanceof Behavior) {
+ if (((Behavior)n).getVisibility() != VisibilityKind.PRIVATE_LITERAL)
+ importedBehaviors.add(n) ;
+ }
+ else if (n instanceof Package) {
+ importedBehaviors.addAll(processPublicallyImportedBehaviors((Package)n)) ;
+ }
+ }
+ for (ElementImport eImport : p.getElementImports()) {
+ if (eImport.getVisibility()!= VisibilityKind.PRIVATE_LITERAL) {
+ PackageableElement element = eImport.getImportedElement() ;
+ if (element instanceof Behavior) {
+ if (eImport.getAlias() != null)
+ importedBehaviors.add(eImport) ;
+ else
+ importedBehaviors.add(element) ;
+ }
+ }
+ }
+ for (PackageImport pImport : p.getPackageImports()) {
+ if (pImport.getVisibility() != VisibilityKind.PRIVATE_LITERAL) {
+ importedBehaviors.addAll(processPublicallyImportedBehaviors(pImport.getImportedPackage())) ;
+ }
+ }
+ return importedBehaviors ;
+ }
+ }
+
+
+
+ protected class EnumerationLiteralNameStrategy implements AlfPartialScope.IGetNameStrategy {
+ public String getName(EObject element) {
+ if (element instanceof EnumerationLiteral) {
+ return ((EnumerationLiteral)element).getName() ;
+ }
+ return "Unexpected element kind..." ;
+ }
+ }
+
+ protected class EnumerationLiteralBuildScopeStrategy implements AlfPartialScope.IBuildScopeStrategy {
+ public List<List<EObject>> buildScope(EObject contextElement) {
+ List<List<EObject>> nestedScopes = new ArrayList<List<EObject>>() ;
+ List<EObject> nestedList = new ArrayList<EObject>() ;
+
+ if (!(contextElement instanceof Enumeration)) {
+ nestedScopes.add(nestedList) ;
+ return nestedScopes ;
+ }
+ Enumeration contextEnumeration = (Enumeration)contextElement ;
+
+ // add all the literals owned by the context enumeration at the first scoping level
+ nestedList.addAll(contextEnumeration.getOwnedLiterals()) ;
+ nestedScopes.add(nestedList) ;
+ // then builds other scoping levels based on context classifier inheritance hierarchy
+
+ List<Classifier> currentGenerals = new ArrayList<Classifier>() ;
+ currentGenerals.addAll(contextEnumeration.getGenerals()) ;
+ List<Classifier> nextGenerals ;
+ while (!currentGenerals.isEmpty()) {
+ nextGenerals = new ArrayList<Classifier>() ;
+ nestedList = new ArrayList<EObject>() ;
+ for (Classifier general : currentGenerals) {
+ nextGenerals.addAll(general.getGenerals()) ;
+ if (general instanceof Enumeration) {
+ for (EnumerationLiteral enumLiteral : ((Enumeration)general).getOwnedLiterals())
+ nestedList.add(enumLiteral) ;
+ }
+ }
+ nestedScopes.add(nestedList) ;
+ currentGenerals = nextGenerals ;
+ }
+ return nestedScopes ;
+ }
+ }
+
+
+ public AlfPartialScope getVisibleEnumerationLiterals(EObject context) {
+ AlfPartialScope.IGetNameStrategy nameStrategy = new EnumerationLiteralNameStrategy() ;
+ AlfPartialScope.IBuildScopeStrategy buildScopeStrategy = new EnumerationLiteralBuildScopeStrategy() ;
+ return new AlfPartialScope(nameStrategy, buildScopeStrategy, context) ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTCommonFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTCommonFactory.java new file mode 100644 index 00000000000..e1abf5075ba --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTCommonFactory.java @@ -0,0 +1,5 @@ +package org.eclipse.papyrus.alf.syntax;
+
+public class ASTCommonFactory {
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTExpressionFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTExpressionFactory.java new file mode 100644 index 00000000000..c8768d1359c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTExpressionFactory.java @@ -0,0 +1,1503 @@ +package org.eclipse.papyrus.alf.syntax;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.papyrus.alf.alf.AdditiveExpression;
+import org.eclipse.papyrus.alf.alf.AndExpression;
+import org.eclipse.papyrus.alf.alf.BOOLEAN_LITERAL;
+import org.eclipse.papyrus.alf.alf.BooleanValue;
+import org.eclipse.papyrus.alf.alf.CollectOrIterateOperation;
+import org.eclipse.papyrus.alf.alf.ConditionalAndExpression;
+import org.eclipse.papyrus.alf.alf.ExclusiveOrExpression;
+import org.eclipse.papyrus.alf.alf.ForAllOrExistsOrOneOperation;
+import org.eclipse.papyrus.alf.alf.INTEGER_LITERAL;
+import org.eclipse.papyrus.alf.alf.InclusiveOrExpression;
+import org.eclipse.papyrus.alf.alf.IsUniqueOperation;
+import org.eclipse.papyrus.alf.alf.LITERAL;
+import org.eclipse.papyrus.alf.alf.LinkOperationTuple;
+import org.eclipse.papyrus.alf.alf.MultiplicativeExpression;
+import org.eclipse.papyrus.alf.alf.NonLiteralValueSpecification;
+import org.eclipse.papyrus.alf.alf.NullExpression;
+import org.eclipse.papyrus.alf.alf.ParenthesizedExpression;
+import org.eclipse.papyrus.alf.alf.PrimaryExpression;
+import org.eclipse.papyrus.alf.alf.QualifiedNamePath;
+import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding;
+import org.eclipse.papyrus.alf.alf.STRING_LITERAL;
+import org.eclipse.papyrus.alf.alf.SelectOrRejectOperation;
+import org.eclipse.papyrus.alf.alf.SuffixExpression;
+import org.eclipse.papyrus.alf.alf.TupleElement;
+import org.eclipse.papyrus.alf.alf.UNLIMITED_LITERAL;
+import org.eclipse.papyrus.alf.alf.UnqualifiedName;
+import org.eclipse.papyrus.alf.syntax.expressions.ArithmeticExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.BitStringUnaryExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.BooleanLiteralExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.BooleanUnaryExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.CastExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.ClassExtentExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.ClassificationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.ConditionalLogicalExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.ConditionalTestExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.EqualityExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+import org.eclipse.papyrus.alf.syntax.expressions.ExtentOrExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.FeatureInvocationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.FeatureReference;
+import org.eclipse.papyrus.alf.syntax.expressions.ForAllOrExistsOrOneExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.InstanceCreationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.InvocationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.IsUniqueExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.IsolationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.LinkOperationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.LogicalExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.NameBinding;
+import org.eclipse.papyrus.alf.syntax.expressions.NameExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.NamedExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.NamedTemplateBinding;
+import org.eclipse.papyrus.alf.syntax.expressions.NamedTuple;
+import org.eclipse.papyrus.alf.syntax.expressions.NaturalLiteralExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.NumericUnaryExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.PositionalTuple;
+import org.eclipse.papyrus.alf.syntax.expressions.PropertyAccessExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+import org.eclipse.papyrus.alf.syntax.expressions.RelationalExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.SelectOrRejectExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceAccessExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceConstructionExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceElements;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceExpressionList;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceOperationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceRange;
+import org.eclipse.papyrus.alf.syntax.expressions.SequenceReductionExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.ShiftExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.StringLiteralExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.SuperInvocationExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.TemplateBinding;
+import org.eclipse.papyrus.alf.syntax.expressions.TemplateParameterSubstitution;
+import org.eclipse.papyrus.alf.syntax.expressions.ThisExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.Tuple;
+import org.eclipse.papyrus.alf.syntax.expressions.UnaryExpression;
+import org.eclipse.papyrus.alf.syntax.expressions.UnboundedLiteralExpression;
+
+public class ASTExpressionFactory {
+ /*
+ * Synthesizes a alf.syntax.expressions.QualifiedName from a QualifiedNameWithBinding
+ */
+ public static final QualifiedName synthesizeQualifiedName(QualifiedNameWithBinding parsed) {
+ QualifiedName synthesized = new QualifiedName() ;
+
+ /* 1. Synthesizes property isAmbigous:boolean */
+ // LIMITATION: The parser implementation only supports :: (no .)
+ // Therefore, a qualified name is never ambiguous
+ synthesized.isAmbiguous = false ;
+
+ /* 2. Synthesizes property nameBinding:List<NameBinding> */
+ synthesized.nameBinding = new ArrayList<NameBinding>() ;
+ synthesized.nameBinding.add(
+ ASTExpressionFactory.synthesizeNameBinding(parsed)) ;
+ QualifiedNameWithBinding remaining = parsed.getRemaining() ;
+ while(remaining != null) {
+ synthesized.nameBinding.add(
+ ASTExpressionFactory.synthesizeNameBinding(remaining)) ;
+ remaining = remaining.getRemaining() ;
+ }
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.QualifiedName from a NameExpression
+ */
+ public static final QualifiedName synthesizeQualifiedName(org.eclipse.papyrus.alf.alf.NameExpression parsed) {
+ QualifiedName synthesized = new QualifiedName() ;
+ /* 1. Synthesizes property isAmbigous:boolean */
+ // LIMITATION: The parser implementation only supports :: (no .)
+ // Therefore, a qualified name is never ambiguous
+ synthesized.isAmbiguous = false ;
+
+ /* 2. Synthesizes property nameBinding:List<NameBinding> */
+ synthesized.nameBinding = new ArrayList<NameBinding>() ;
+ if (parsed.getPath() != null) {
+ QualifiedNamePath path = parsed.getPath() ;
+ for (UnqualifiedName pathElement : path.getNamespace()) {
+ synthesized.nameBinding.add(ASTExpressionFactory.synthesizeNameBinding(pathElement)) ;
+ }
+ }
+ // Finally add the last name binding (i.e., parsed.id)
+ // LIMITATION: The parser implementation does not support a template binding for the last element of the path
+ NameBinding last = new NameBinding() ;
+ last.name = parsed.getId() ;
+ synthesized.nameBinding.add(last) ;
+
+ // TODO: raise an error in the cases where the following properties have a value:
+ // - prefixOp
+ // - invocationCompletion
+ // - sequenceConstructionCompletion
+ // - postfixOp
+ // - suffix
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.QualifiedName from a NameExpression
+ */
+ public static final QualifiedName synthesizeQualifiedName(
+ org.eclipse.papyrus.alf.alf.Expression parsed) {
+ // TODO Raise an error in the case where "parsed" does not finally resolve to a NameExpression
+ org.eclipse.papyrus.alf.alf.ConditionalTestExpression tmp1 =
+ (org.eclipse.papyrus.alf.alf.ConditionalTestExpression)parsed ;
+ if (tmp1.getWhenFalse() != null || tmp1.getWhenTrue() != null)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.ConditionalOrExpression tmp2 = tmp1.getExp() ;
+ if (tmp2.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.ConditionalAndExpression tmp3 = tmp2.getExp().get(0) ;
+ if (tmp3.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.InclusiveOrExpression tmp4 = tmp3.getExp().get(0) ;
+ if (tmp4.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.ExclusiveOrExpression tmp5 = tmp4.getExp().get(0) ;
+ if (tmp5.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.AndExpression tmp6 = tmp5.getExp().get(0) ;
+ if (tmp6.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.EqualityExpression tmp7 = tmp6.getExp().get(0) ;
+ if (tmp7.getOp().size() != 0)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.ClassificationExpression tmp8 = tmp7.getExp().get(0) ;
+ if (tmp8.getOp() != null && !tmp8.getOp().equals(""))
+ //error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.RelationalExpression tmp9 = tmp8.getExp() ;
+ if (tmp9.getOp() != null && !tmp9.getOp().equals(""))
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.ShiftExpression tmp10 = tmp9.getLeft() ;
+ if (tmp10.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.AdditiveExpression tmp11 = tmp10.getExp().get(0) ;
+ if (tmp11.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.MultiplicativeExpression tmp12 = tmp11.getExp().get(0) ;
+ if (tmp12.getExp().size() != 1)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.UnaryExpression tmp13 = tmp12.getExp().get(0) ;
+ if (tmp13.getOp() != null && !tmp13.getOp().equals(""))
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.PrimaryExpression tmp14 = tmp13.getExp() ;
+ if (tmp14.getPrefix() == null)
+ // error
+ return new QualifiedName() ;
+ org.eclipse.papyrus.alf.alf.ValueSpecification tmp15 = tmp14.getPrefix() ;
+
+ if (! (tmp15 instanceof org.eclipse.papyrus.alf.alf.NameExpression))
+ // error
+ return new QualifiedName() ;
+
+ return ASTExpressionFactory.synthesizeQualifiedName((org.eclipse.papyrus.alf.alf.NameExpression)tmp15) ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.QualifiedName from a alf.syntax.expressions.Expression
+ */
+ public static final QualifiedName synthesizeQualifiedName(Expression synthesized) {
+ if (synthesized instanceof NameExpression)
+ return ((NameExpression) synthesized).name ;
+ return new QualifiedName() ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.NameBinding from a QualifiedNameWithBinding
+ */
+ public static final NameBinding synthesizeNameBinding(QualifiedNameWithBinding parsed) {
+ NameBinding synthesized = new NameBinding() ;
+ /* 1. Synthesizes property name:String */
+ synthesized.name = "" + parsed.getId() ;
+
+ /* 2. Synthesizes property binding:TemplateBinding */
+ if (parsed.getBinding() != null) {
+ synthesized.binding =
+ ASTExpressionFactory.synthesizeTemplateBinding(parsed.getBinding()) ;
+ }
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.NameBinding from a String
+ */
+ public static final NameBinding synthesizeNameBinding(String parsed) {
+ NameBinding synthesized = new NameBinding() ;
+ /* 1. Synthesizes property name:String */
+ synthesized.name = "" + parsed ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.NameBinding from a UnqualifiedName
+ */
+ public static final NameBinding synthesizeNameBinding(UnqualifiedName parsed) {
+ NameBinding synthesized = new NameBinding() ;
+ /* 1. Synthesizes property name:String */
+ synthesized.name = "" + parsed.getName() ;
+
+ /* 2. Synthesizes property binding:TemplateBinding */
+ if (parsed.getTemplateBinding() != null) {
+ synthesized.binding =
+ ASTExpressionFactory.synthesizeTemplateBinding(parsed.getTemplateBinding()) ;
+ }
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a import alf.syntax.expressions.TemplateBinding from a TemplateBinding
+ */
+ public static final TemplateBinding synthesizeTemplateBinding(org.eclipse.papyrus.alf.alf.TemplateBinding parsed) {
+ // LIMITATION: In this implementation of the Alf parser, only NamedTemplateBinding are supported
+ return ASTExpressionFactory.synthesizeNamedTemplateBinding(parsed) ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.NamedTemplateBinding from a TemplateBinding
+ */
+ public static final NamedTemplateBinding synthesizeNamedTemplateBinding(org.eclipse.papyrus.alf.alf.TemplateBinding parsed) {
+ NamedTemplateBinding synthesized = new NamedTemplateBinding() ;
+
+ /*1. Synthesizes property substitution:List<TemplateParameterSubstitution> */
+ synthesized.substitution = new ArrayList<TemplateParameterSubstitution>() ;
+ for (org.eclipse.papyrus.alf.alf.NamedTemplateBinding s : parsed.getBindings()) {
+ synthesized.substitution.add(
+ ASTExpressionFactory.synthesizeTemplateParameterSubstitution(s)) ;
+ }
+ return synthesized ;
+ }
+ /*
+ * Synthesizes a alf.syntax.expressions.TemplateParameterSubstitution from a NamedTemplateBinding
+ * NOTE: The class NamedTemplateBinding, from the implementation of the Alf grammar, is misleading
+ * Should be TemplateParameterSubsitution
+ */
+ public static final TemplateParameterSubstitution synthesizeTemplateParameterSubstitution(org.eclipse.papyrus.alf.alf.NamedTemplateBinding parsed) {
+ TemplateParameterSubstitution synthesized = new TemplateParameterSubstitution() ;
+
+ /* 1. Synthesizes property parameterName:String */
+ synthesized.parameterName = parsed.getFormal() ;
+
+ /* 2. Synthesizes property argumentName:QualifiedName */
+ synthesized.argumentName =
+ ASTExpressionFactory.synthesizeQualifiedName(parsed.getActual()) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from an Expression
+ */
+ public static final Expression synthesizeExpression(org.eclipse.papyrus.alf.alf.Expression parsed) {
+
+ // In this implementation of the Alf parser, rule Expression can only
+ // produce a ConditionalTestExpression
+ // NOTE: In the Alf spec, Expression can also produce an AssignmentExpression,
+ // which are not directly supported by our parser.
+ return ASTExpressionFactory.synthesizeConditionalTestExpression((org.eclipse.papyrus.alf.alf.ConditionalTestExpression)parsed);
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ParenthesizedExpression
+ */
+ public static final Expression synthesizeExpression(ParenthesizedExpression parsed) {
+ // first check it is really a ParenthesizedExpression
+ if (parsed.getCasted() == null) {
+ // this is a ParenthesizedExpression
+ Expression synthesized = ASTExpressionFactory.synthesizeExpression(parsed.getExpOrTypeCast()) ;
+ if (parsed.getSuffix() != null)
+ return ASTExpressionFactory.synthesizeExpression(synthesized, parsed.getSuffix()) ;
+ return synthesized ;
+ }
+
+ // this is not a ParenthesizedExpression, i.e., this is a cast expression
+ return ASTExpressionFactory.synthesizeCastExpression(parsed) ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a NameExpression
+ */
+ public static final Expression synthesizeExpression(org.eclipse.papyrus.alf.alf.NameExpression exp) {
+ // TODO Auto-generated method stub
+ return new Expression();
+ }
+
+
+ public static final Expression synthesizeCastExpression(ParenthesizedExpression parsed) {
+ CastExpression synthesized = new CastExpression() ;
+
+ /* 1. Synthesizes property operand:Expression */
+ synthesized.operand = ASTExpressionFactory.synthesizePrimaryExpression(parsed.getCasted()) ;
+
+ /* 2. Synthesizes property typeName:QualifiedName */
+ synthesized.typeName = ASTExpressionFactory.synthesizeQualifiedName(parsed.getExpOrTypeCast()) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ConditionTestExpression
+ */
+ public static final Expression synthesizeConditionalTestExpression(org.eclipse.papyrus.alf.alf.ConditionalTestExpression parsed) {
+ // First checks if it is actually a ConditionalTestExpression
+ if (parsed.getWhenFalse() != null || parsed.getWhenTrue() != null) {
+ // This is a ConditionalTestExpression
+ ConditionalTestExpression synthesized = new ConditionalTestExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeConditionalLogicalExpression(parsed.getExp()) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeConditionalTestExpression(parsed.getWhenTrue()) ;
+
+ /* 3. Synthesizes property operand3:Expression */
+ synthesized.operand3 = ASTExpressionFactory.synthesizeConditionalTestExpression(parsed.getWhenFalse()) ;
+
+ return synthesized ;
+ }
+
+ // This is not a ConditionalTestExpression
+ return ASTExpressionFactory.synthesizeConditionalLogicalExpression(parsed.getExp()) ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ConditionalOrExpression
+ */
+ public static final Expression synthesizeConditionalLogicalExpression(org.eclipse.papyrus.alf.alf.ConditionalOrExpression parsed) {
+
+ // First check if it is a ConditionalOrExpression
+ if (parsed.getExp().size() == 1)
+ // This is not a ConditionalOrExpression
+ return ASTExpressionFactory.synthesizeConditionalLogicalExpression(parsed.getExp().get(0)) ;
+
+ // This is a ConditionalOrExpression
+ ConditionalLogicalExpression synthesized = new ConditionalLogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeConditionalLogicalExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeConditionalLogicalExpression(parsed.getExp().subList(1, parsed.getExp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "||" ;
+
+ return synthesized ;
+
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ConditionalAndExpression
+ */
+ public static final Expression synthesizeConditionalLogicalExpression(
+ ConditionalAndExpression parsed) {
+ //first check if it is a ConditionalAndExpression
+ if (parsed.getExp().size() == 1)
+ // This is not a ConditionalAndExpression
+ return ASTExpressionFactory.synthesizeLogicalExpression(parsed.getExp().get(0)) ;
+
+ // This is a ConditionalAndExpression
+ ConditionalLogicalExpression synthesized = new ConditionalLogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeLogicalExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfInclusiveOrExpression (parsed.getExp().subList(1, parsed.getExp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "&&" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list ConditionalAndExpression
+ * representing a flat ConditionalAndExpression
+ */
+ public static final Expression synthesizeConditionalLogicalExpression(
+ List<ConditionalAndExpression> flatParsed) {
+
+ //first check if it is a ConditionalAndExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat ConditionalAndExpression
+ return ASTExpressionFactory.synthesizeConditionalLogicalExpression(flatParsed.get(0)) ;
+
+ // This is a flat ConditionalAndExpression
+ ConditionalLogicalExpression synthesized = new ConditionalLogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeConditionalLogicalExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeConditionalLogicalExpression(flatParsed.subList(1, flatParsed.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "&&" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a InclusiveOrExpression
+ */
+ public static final Expression synthesizeLogicalExpression(
+ InclusiveOrExpression parsed) {
+ //first check if it is an InclusiveOrExpression
+ if (parsed.getExp().size() == 1)
+ // This is not an InclusiveOrExpression
+ return ASTExpressionFactory.synthesizeLogicalExpression(parsed.getExp().get(0)) ;
+
+ // This is an InclusiveOrExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeLogicalExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfExclusiveOrExpression(parsed.getExp().subList(1, parsed.getExp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "|" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of InclusiveOrExpression
+ * representing a flat InclusiveOrExpression
+ */
+ public static final Expression synthesizeLogicalExpressionFromListOfInclusiveOrExpression (
+ List<InclusiveOrExpression> flatParsed) {
+ //first check if it is a flat InclusiveOrExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat InclusiveOrExpression
+ return ASTExpressionFactory.synthesizeLogicalExpression(flatParsed.get(0)) ;
+
+ // This is a flat InclusiveOrExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeLogicalExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfInclusiveOrExpression (flatParsed.subList(1, flatParsed.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "|" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ExclusiveOrExpression
+ */
+ public static final Expression synthesizeLogicalExpression(
+ ExclusiveOrExpression parsed) {
+ //first check if it is an ExclusiveOrExpression
+ if (parsed.getExp().size() == 1)
+ // This is not an ExclusiveOrExpression
+ return ASTExpressionFactory.synthesizeLogicalExpression(parsed.getExp().get(0)) ;
+
+ // This is an InclusiveOrExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeLogicalExpression(parsed.getExp().get(0));
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfAndExpression(parsed.getExp().subList(1, parsed.getExp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "^" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of ExclusiveOrExpression
+ * representing a flat ExclusiveOrExpression
+ */
+ public static final Expression synthesizeLogicalExpressionFromListOfExclusiveOrExpression(
+ List<ExclusiveOrExpression> flatParsed) {
+ //first check if it is a flat ExclusiveOrExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat ExclusiveOrExpression
+ return ASTExpressionFactory.synthesizeLogicalExpression(flatParsed.get(0)) ;
+
+ // This is a flat ExclusiveOrExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeLogicalExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfExclusiveOrExpression (flatParsed.subList(1, flatParsed.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "^" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a AndExpression
+ */
+ public static final Expression synthesizeLogicalExpression(AndExpression parsed) {
+ //first check if it is an AndExpression
+ if (parsed.getExp().size() == 1)
+ // This is not an AndExpression
+ return ASTExpressionFactory.synthesizeEqualityExpression(parsed.getExp().get(0)) ;
+
+ // This is an AndOrExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeEqualityExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfEqualityExpression(parsed.getExp().subList(1, parsed.getExp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "&" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of EqualityExpression
+ * representing a flat AndExpression
+ */
+ public static final Expression synthesizeLogicalExpressionFromListOfEqualityExpression(
+ List<org.eclipse.papyrus.alf.alf.EqualityExpression> flatParsed) {
+ //first check if it is a flat AndExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat AndExpression
+ return ASTExpressionFactory.synthesizeEqualityExpression(flatParsed.get(0)) ;
+
+ // This is a flat AndExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeEqualityExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfEqualityExpression (flatParsed.subList(1, flatParsed.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "&" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of AndExpression
+ * representing a flat AndExpression
+ */
+ public static final Expression synthesizeLogicalExpressionFromListOfAndExpression(
+ List<AndExpression> flatParsed) {
+ //first check if it is a flat AndExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat AndExpression
+ return ASTExpressionFactory.synthesizeLogicalExpression(flatParsed.get(0)) ;
+
+ // This is a flat AndExpression
+ LogicalExpression synthesized = new LogicalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeLogicalExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeLogicalExpressionFromListOfAndExpression (flatParsed.subList(1, flatParsed.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = "&" ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a EqualityExpression
+ */
+ public static final Expression synthesizeEqualityExpression(
+ org.eclipse.papyrus.alf.alf.EqualityExpression parsed) {
+ //first check if it is an EqualityExpression
+ if (parsed.getExp().size() == 1)
+ // This is not an EqualityExpression
+ return ASTExpressionFactory.synthesizeClassificationExpression(parsed.getExp().get(0)) ;
+
+ // This is an EqualityExpression
+ EqualityExpression synthesized = new EqualityExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeClassificationExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeEqualityExpression(parsed.getExp().subList(1, parsed.getExp().size()),
+ parsed.getOp().subList(1, parsed.getOp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp().get(0) ;
+
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of ClassificationExpression
+ * and (equality) operators representing a flat EqualityExpression
+ */
+ public static final Expression synthesizeEqualityExpression(
+ List<org.eclipse.papyrus.alf.alf.ClassificationExpression> flatParsed,
+ List<String> operators) {
+ //first check if it is a flat EqualityExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat EqualityExpression
+ return ASTExpressionFactory.synthesizeClassificationExpression(flatParsed.get(0)) ;
+
+ // This is a flat EqualityExpression
+ EqualityExpression synthesized = new EqualityExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeClassificationExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeEqualityExpression (flatParsed.subList(1, flatParsed.size()),
+ operators.subList(1, operators.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = operators.get(0) ;
+
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ClassificationExpression
+ */
+ public static final Expression synthesizeClassificationExpression(
+ org.eclipse.papyrus.alf.alf.ClassificationExpression parsed) {
+ //first check if it is a ClassificationExpression
+ if (parsed.getOp() == null || parsed.getOp().equals(""))
+ // This is not a ClassificationExpression
+ return ASTExpressionFactory.synthesizeRelationalExpression(parsed.getExp()) ;
+
+ // This is a ClassificationExpression
+ ClassificationExpression synthesized = new ClassificationExpression() ;
+ /* 1. Synthesizes property operand:Expression */
+ synthesized.operand= ASTExpressionFactory.synthesizeRelationalExpression(parsed.getExp()) ;
+
+ /* 2. Synthesizes property typename:QualifiedName */
+ synthesized.typeName = ASTExpressionFactory.synthesizeQualifiedName(parsed.getTypeName()) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp() ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a RelationalExpression
+ */
+ public static final Expression synthesizeRelationalExpression(org.eclipse.papyrus.alf.alf.RelationalExpression parsed) {
+ //first check if it is a RelationalExpression
+ if (parsed.getOp() == null || parsed.getOp().equals(""))
+ // This is not a RelationalExpression
+ return ASTExpressionFactory.synthesizeShiftExpression(parsed.getLeft()) ;
+
+ // This is a RelationalExpression
+ RelationalExpression synthesized = new RelationalExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1= ASTExpressionFactory.synthesizeShiftExpression(parsed.getLeft()) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeShiftExpression(parsed.getRight()) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp() ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ShiftExpression
+ */
+ public static final Expression synthesizeShiftExpression(org.eclipse.papyrus.alf.alf.ShiftExpression parsed) {
+ //first check if it is a ShiftExpression
+ if (parsed.getExp().size() == 1)
+ // This is not a ShiftExpression
+ return ASTExpressionFactory.synthesizeArithmeticExpression(parsed.getExp().get(0)) ;
+
+ // This is a ShiftExpression
+ ShiftExpression synthesized = new ShiftExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1= ASTExpressionFactory.synthesizeArithmeticExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeArithmeticExpression(parsed.getExp().get(1)) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp() ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a AdditiveExpression
+ */
+ public static final Expression synthesizeArithmeticExpression(
+ AdditiveExpression parsed) {
+ //first check if it is a AdditiveExpression
+ if (parsed.getExp().size() == 1)
+ // This is not a ShiftExpression
+ return ASTExpressionFactory.synthesizeArithmeticExpression(parsed.getExp().get(0)) ;
+
+ // This is a ShiftExpression
+ ArithmeticExpression synthesized = new ArithmeticExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1= ASTExpressionFactory.synthesizeArithmeticExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeArithmeticExpressionFromListOfMultiplicativeExpression(parsed.getExp().subList(1, parsed.getExp().size()),
+ parsed.getOp().subList(1, parsed.getOp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp().get(0) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of AdditiveExpression
+ * and (additive) operators representing a flat AdditiveExpression
+ */
+ public static final Expression synthesizeArithmeticExpressionFromListOfMultiplicativeExpression(
+ List<MultiplicativeExpression> flatParsed, List<String> operators) {
+ //first check if it is a flat AdditiveExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat AdditiveExpression
+ return ASTExpressionFactory.synthesizeArithmeticExpression(flatParsed.get(0)) ;
+
+ // This is a flat AdditiveExpression
+ EqualityExpression synthesized = new EqualityExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeArithmeticExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeArithmeticExpressionFromListOfMultiplicativeExpression(flatParsed.subList(1, flatParsed.size()),
+ operators.subList(1, operators.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = operators.get(0) ;
+
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a MultiplicativeExpression
+ */
+ public static final Expression synthesizeArithmeticExpression(
+ MultiplicativeExpression parsed) {
+ //first check if it is a MultiplicativeExpression
+ if (parsed.getExp().size() == 1)
+ // This is not a MultiplicativeExpression
+ return ASTExpressionFactory.synthesizeUnaryExpression(parsed.getExp().get(0)) ;
+
+ // This is a MultiplicativeExpression
+ ArithmeticExpression synthesized = new ArithmeticExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1= ASTExpressionFactory.synthesizeUnaryExpression(parsed.getExp().get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeArithmeticExpressionFromListOfUnaryExpression(parsed.getExp().subList(1, parsed.getExp().size()),
+ parsed.getOp().subList(1, parsed.getOp().size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp().get(0) ;
+
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a list of UnaryExpression
+ * and (multiplicative) operators representing a flat MultiplicativeExpression
+ */
+ public static final Expression synthesizeArithmeticExpressionFromListOfUnaryExpression(
+ List<org.eclipse.papyrus.alf.alf.UnaryExpression> flatParsed,
+ List<String> operators) {
+ //first check if it is a flat MultiplicativeExpression
+ if (flatParsed.size() == 1)
+ // This is not a flat MultiplicativeExpression
+ return ASTExpressionFactory.synthesizeUnaryExpression(flatParsed.get(0)) ;
+
+ // This is a flat MultiplicativeExpression
+ EqualityExpression synthesized = new EqualityExpression() ;
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand1 = ASTExpressionFactory.synthesizeUnaryExpression(flatParsed.get(0)) ;
+
+ /* 2. Synthesizes property operand2:Expression */
+ synthesized.operand2 = ASTExpressionFactory.synthesizeArithmeticExpressionFromListOfUnaryExpression(flatParsed.subList(1, flatParsed.size()),
+ operators.subList(1, operators.size())) ;
+
+ /* 3. Synthesizes property operator:String */
+ synthesized.operator = operators.get(0) ;
+
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a UnaryExpression
+ */
+ public static final Expression synthesizeUnaryExpression(
+ org.eclipse.papyrus.alf.alf.UnaryExpression parsed) {
+ //first check if it is a UnaryExpression
+ if (parsed.getOp() == null || parsed.getOp().equals(""))
+ // This is not a UnaryExpression
+ return ASTExpressionFactory.synthesizePrimaryExpression(parsed.getExp()) ;
+
+ // This is a UnaryExpression
+ UnaryExpression synthesized = new UnaryExpression() ;
+ // depending on the operator, synthesizes the right kind of UnaryExpression
+ if (parsed.getOp().equals("!"))
+ synthesized = new BooleanUnaryExpression() ;
+ else if (parsed.getOp().equals("$"))
+ synthesized = new IsolationExpression() ;
+ else if (parsed.getOp().equals("~"))
+ synthesized = new BitStringUnaryExpression() ;
+ else // "+" or "-" unary operators
+ synthesized = new NumericUnaryExpression() ;
+
+ /* 1. Synthesizes property operand1:Expression */
+ synthesized.operand= ASTExpressionFactory.synthesizePrimaryExpression(parsed.getExp()) ;
+
+ /* 2. Synthesizes property operator:String */
+ synthesized.operator = parsed.getOp() ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a PrimaryExpression
+ */
+ public static final Expression synthesizePrimaryExpression(PrimaryExpression exp) {
+ if (exp.getPrefix() instanceof org.eclipse.papyrus.alf.alf.LITERAL)
+ return ASTExpressionFactory.synthesizeLiteralExpression(
+ (org.eclipse.papyrus.alf.alf.LITERAL) exp.getPrefix()) ;
+ else if (exp.getPrefix() instanceof org.eclipse.papyrus.alf.alf.ThisExpression)
+ return ASTExpressionFactory.synthesizeThisExpression(
+ (org.eclipse.papyrus.alf.alf.ThisExpression) exp.getPrefix()) ;
+ else if (exp.getPrefix() instanceof org.eclipse.papyrus.alf.alf.SuperInvocationExpression)
+ return ASTExpressionFactory.synthesizeSuperInvocationExpression(
+ (org.eclipse.papyrus.alf.alf.SuperInvocationExpression) exp.getPrefix()) ;
+ else if (exp.getPrefix() instanceof org.eclipse.papyrus.alf.alf.InstanceCreationExpression)
+ return ASTExpressionFactory.synthesizeInstanceCreationExpression(
+ (org.eclipse.papyrus.alf.alf.InstanceCreationExpression) exp.getPrefix()) ;
+ else if (exp.getPrefix() instanceof org.eclipse.papyrus.alf.alf.ParenthesizedExpression)
+ return ASTExpressionFactory.synthesizeExpression(
+ (org.eclipse.papyrus.alf.alf.ParenthesizedExpression) exp.getPrefix()) ;
+ else if (exp.getPrefix() instanceof org.eclipse.papyrus.alf.alf.NameExpression)
+ return ASTExpressionFactory.synthesizeExpression(
+ (org.eclipse.papyrus.alf.alf.NameExpression) exp.getPrefix()) ;
+ else // NullExpression
+ return ASTExpressionFactory.synthesizeSequenceConstructionExpression(
+ (org.eclipse.papyrus.alf.alf.NullExpression) exp.getPrefix()) ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a NullExpression
+ */
+ public static final Expression synthesizeSequenceConstructionExpression(
+ NullExpression exp) {
+ SequenceConstructionExpression synthesized = new SequenceConstructionExpression() ;
+ /*. No property to synthesize */
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a NonLiteralValueSpecification
+ */
+ public static final Expression synthesizePrimaryExpression(NonLiteralValueSpecification exp) {
+ if (exp instanceof org.eclipse.papyrus.alf.alf.ThisExpression)
+ return ASTExpressionFactory.synthesizeThisExpression(
+ (org.eclipse.papyrus.alf.alf.ThisExpression) exp) ;
+ else if (exp instanceof org.eclipse.papyrus.alf.alf.SuperInvocationExpression)
+ return ASTExpressionFactory.synthesizeSuperInvocationExpression(
+ (org.eclipse.papyrus.alf.alf.SuperInvocationExpression) exp) ;
+ else if (exp instanceof org.eclipse.papyrus.alf.alf.InstanceCreationExpression)
+ return ASTExpressionFactory.synthesizeInstanceCreationExpression(
+ (org.eclipse.papyrus.alf.alf.InstanceCreationExpression) exp) ;
+ else if (exp instanceof org.eclipse.papyrus.alf.alf.ParenthesizedExpression)
+ return ASTExpressionFactory.synthesizeExpression(
+ (org.eclipse.papyrus.alf.alf.ParenthesizedExpression) exp) ;
+ else // NameExpression
+ return ASTExpressionFactory.synthesizeExpression(
+ (org.eclipse.papyrus.alf.alf.NameExpression) exp) ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a LITERAL
+ */
+ public static final Expression synthesizeLiteralExpression(LITERAL parsed) {
+ if (parsed instanceof INTEGER_LITERAL) {
+ NaturalLiteralExpression synthesized = new NaturalLiteralExpression() ;
+ /* 1. Synthesizes property image:String */
+ synthesized.image = ((INTEGER_LITERAL) parsed).getValue() ;
+ return synthesized ;
+ }
+ else if (parsed instanceof UNLIMITED_LITERAL) {
+ UnboundedLiteralExpression synthesized = new UnboundedLiteralExpression() ;
+ /*. No properties to synthesize */
+ return synthesized ;
+ }
+ else if (parsed instanceof STRING_LITERAL) {
+ StringLiteralExpression synthesized = new StringLiteralExpression() ;
+ /* 1. Synthesizes property image:String */
+ synthesized.image = ((STRING_LITERAL) parsed).getValue() ;
+ return synthesized ;
+ }
+ else { // BOOLEAN_LITERAL
+ BOOLEAN_LITERAL castedExp = (BOOLEAN_LITERAL)parsed ;
+ BooleanLiteralExpression synthesized = new BooleanLiteralExpression() ;
+ /* 1. Synthesizes property image:String */
+ if (castedExp.getValue() == BooleanValue.TRUE)
+ synthesized.image = "true" ;
+ else
+ synthesized.image = "false" ;
+ return synthesized ;
+ }
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a ThisExpression
+ */
+ public static final Expression synthesizeThisExpression(org.eclipse.papyrus.alf.alf.ThisExpression parsed) {
+ ThisExpression synthesized = new ThisExpression() ;
+ /*. No properties to synthesize */
+ if (parsed.getSuffix() != null)
+ return ASTExpressionFactory.synthesizeExpression(synthesized, parsed.getSuffix()) ;
+ return synthesized ;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a SuperInvocationExpression
+ */
+ public static final Expression synthesizeSuperInvocationExpression(
+ org.eclipse.papyrus.alf.alf.SuperInvocationExpression parsed) {
+ SuperInvocationExpression synthesized = new SuperInvocationExpression() ;
+
+ /* 1. Synthesizes property target:QualifiedName */
+ if (parsed.getOperationName() != null)
+ synthesized.target = ASTExpressionFactory.synthesizeQualifiedName(parsed.getOperationName()) ;
+
+ /* 2. Synthesizes property tuple:Tuple */
+ synthesized.tuple = ASTExpressionFactory.synthesizeTuple(parsed.getTuple(), synthesized) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Tuple from a Tuple
+ */
+ public static final Tuple synthesizeTuple(org.eclipse.papyrus.alf.alf.Tuple parsed,
+ InvocationExpression invocation) {
+ // LIMITATION: This implementation of the Alf Parser only supports positional tuples
+ return ASTExpressionFactory.synthesizePositionalTuple(parsed, invocation);
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.PositionalTuple from a Tuple
+ */
+ public static final Tuple synthesizePositionalTuple(
+ org.eclipse.papyrus.alf.alf.Tuple parsed,
+ InvocationExpression invocation) {
+ PositionalTuple synthesized = new PositionalTuple() ;
+
+ /* 1. Synthesizes property expression:List<Expression> */
+ synthesized.expression = new ArrayList<Expression>() ;
+ for (TupleElement t :parsed.getTupleElements()) {
+ synthesized.expression.add(ASTExpressionFactory.synthesizeExpression(t.getArgument())) ;
+ }
+
+ /* 2. Synthesizes property invocation:InvocationExpression */
+ synthesized.invocation = invocation ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Tuple from a LinkOperationTuple
+ */
+ public static final Tuple synthesizeNamedTupleFromLinkOperationExpression(LinkOperationTuple tuple,
+ LinkOperationExpression invocation) {
+ NamedTuple synthesized = new NamedTuple() ;
+
+ /*1. Synthesize property invocation:InvocationExpression */
+ synthesized.invocation = invocation ;
+
+ /*2. Synthesize property namedExpression:List<NamedExpression> */
+ synthesized.namedExpression = new ArrayList<NamedExpression>() ;
+ //NamedExpression n ;
+ // Hypothesis: All LinkOperationTupleElement have both a "objectOrRole" and an "object"
+// for (LinkOperationTupleElement t : tuple.getLinkOperationTupleElement()) {
+// n = new NamedExpression() ;
+// n.name = t.getObjectOrRole() ;
+// if (t.getRoleIndex() != null)
+// n.index = this.synthesizeExpression(t.getRoleIndex()) ;
+// n.expression = this.synthesizeNameExpression(t.getObject()) ;
+// synthesized.namedExpression.add(n) ;
+// }
+
+ return synthesized ;
+ }
+
+ public static final Expression synthesizeNameExpression(String object) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a InstanceCreationExpression
+ */
+ public static final Expression synthesizeInstanceCreationExpression(
+ org.eclipse.papyrus.alf.alf.InstanceCreationExpression parsed) {
+ InstanceCreationExpression synthesized = new InstanceCreationExpression() ;
+
+ /* 1. Synthesizes property target:QualifiedName */
+ synthesized.constructor = ASTExpressionFactory.synthesizeQualifiedName(parsed.getConstructor()) ;
+
+// /* 2. Synthesizes property tuple:Tuple */
+// synthesized.tuple = this.synthesizeTuple(parsed.getTuple(), synthesized) ;
+
+ if (parsed.getSuffix() != null)
+ return ASTExpressionFactory.synthesizeExpression(synthesized, parsed.getSuffix()) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a SuffixExpression
+ */
+ public static final Expression synthesizeExpression(
+ Expression synthesized, SuffixExpression suffix) {
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.OperationCallExpression)
+ return ASTExpressionFactory.synthesizeFeatureInvocationExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.OperationCallExpression)suffix) ;
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.PropertyCallExpression)
+ return ASTExpressionFactory.synthesizePropertyAccessExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.PropertyCallExpression)suffix) ;
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.LinkOperationExpression)
+ return ASTExpressionFactory.synthesizeLinkOperationExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.LinkOperationExpression)suffix) ;
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.SequenceOperationExpression)
+ return ASTExpressionFactory.synthesizeSequenceOperationExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.SequenceOperationExpression)suffix) ;
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.SequenceReductionExpression)
+ return ASTExpressionFactory.synthesizeSequenceReductionExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.SequenceReductionExpression)suffix) ;
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.SequenceExpansionExpression)
+ return ASTExpressionFactory.synthesizeSequenceExpansionExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.SequenceExpansionExpression)suffix) ;
+ else // org.eclipse.papyrus.alf.alf.ClassExtentExpression
+ return ASTExpressionFactory.synthesizeClassExtentExpression(
+ synthesized,
+ (org.eclipse.papyrus.alf.alf.ClassExtentExpression)suffix) ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix OperationCallExpression
+ */
+ public static final Expression synthesizeFeatureInvocationExpression(
+ Expression target, org.eclipse.papyrus.alf.alf.OperationCallExpression suffix) {
+ FeatureInvocationExpression synthesized = new FeatureInvocationExpression() ;
+
+ /*1. Synthesizes property tuple:Tuple */
+ synthesized.tuple = ASTExpressionFactory.synthesizeTuple(suffix.getTuple(), synthesized) ;
+
+ /*2. Synthesizes property target:FeatureReference */
+ FeatureReference featureReference = new FeatureReference() ;
+ featureReference.expression = target ;
+ featureReference.nameBinding = ASTExpressionFactory.synthesizeNameBinding(suffix.getOperationName()) ;
+ synthesized.target = featureReference ;
+
+ if (suffix.getSuffix() != null)
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix PropertyCallExpression
+ */
+ public static final Expression synthesizePropertyAccessExpression(Expression target,
+ org.eclipse.papyrus.alf.alf.PropertyCallExpression suffix) {
+ PropertyAccessExpression synthesized = new PropertyAccessExpression() ;
+ /*1. Synthesize property featureReference */
+ FeatureReference featureReference = new FeatureReference() ;
+ featureReference.expression = target ;
+ // LIMITATION: in this version of the Alf parser, no binding can be specified in a property access expression
+ NameBinding nameBinding = new NameBinding() ;
+ nameBinding.name = suffix.getPropertyName() ;
+ featureReference.nameBinding = nameBinding ;
+ synthesized.featureReference = featureReference ;
+
+ Expression resultingExpression = synthesized ;
+
+ // in the case where an index is specified, needs to synthesize a SequenceAccessExpression
+ if (suffix.getIndex() != null) {
+ SequenceAccessExpression synthesizedAccessExpression = new SequenceAccessExpression() ;
+ synthesizedAccessExpression.primary = synthesized ;
+ synthesizedAccessExpression.index =
+ ASTExpressionFactory.synthesizeExpression(suffix.getIndex()) ;
+ resultingExpression = synthesizedAccessExpression ;
+ }
+
+ if (suffix.getSuffix() != null)
+ return ASTExpressionFactory.synthesizeExpression(resultingExpression, suffix.getSuffix()) ;
+
+ return resultingExpression ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix LinkCallExpression
+ */
+ public static final Expression synthesizeLinkOperationExpression(
+ Expression target, org.eclipse.papyrus.alf.alf.LinkOperationExpression suffix) {
+ LinkOperationExpression synthesized = new LinkOperationExpression() ;
+
+ /*1. Synthesize property tuple:Tuple */
+ synthesized.tuple = ASTExpressionFactory.synthesizeNamedTupleFromLinkOperationExpression(suffix.getTuple(), synthesized) ;
+
+ /*2. Synthesize property associationName:QualifiedName */
+ synthesized.associationName = ASTExpressionFactory.synthesizeQualifiedName(target) ;
+
+ /*3. Synthesize property operation:String */
+ switch (suffix.getKind()) {
+ case CLEAR:
+ synthesized.operation = "clearAssoc" ;
+ break;
+ case CREATE:
+ synthesized.operation = "createLink" ;
+ break;
+ case DESTROY:
+ synthesized.operation = "destroyLink" ;
+ break;
+ }
+
+ return synthesized ;
+ }
+
+ /**
+ * Build a alf.syntax.expressions.SequenceConstructionExpression from a SequenceConstructionExpression
+ * @param parsed
+ * @return The SequenceConstructionExpression
+ */
+ public static final Expression synthesizeSequenceConstructionExpression(
+ org.eclipse.papyrus.alf.alf.SequenceConstructionExpression parsed){
+ SequenceConstructionExpression synthesized = null;
+ if(parsed != null){
+ synthesized = new SequenceConstructionExpression();
+ if(parsed.getSequenceElement()!=null){
+ /*0. Determine if we want to generate a SequenceExpressionList or a SequenceRange*/
+ if(parsed.getRangeUpper() != null){
+ SequenceRange seqRange = new SequenceRange();
+ seqRange.rangeUpper = ASTExpressionFactory.synthesizeExpression(parsed.getRangeUpper());
+ NaturalLiteralExpression literalExp = new NaturalLiteralExpression();
+ literalExp.image = "0";
+ seqRange.rangeLower = literalExp;
+ }else{
+ synthesized.elements = ASTExpressionFactory.synthesizeSequenceExpressionList(
+ parsed.getSequenceElement());
+ }
+ }
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.expressions.SequenceExpressionList from a list of SequenceElement
+ * @param seqElts
+ * @return The SequenceExpressionList
+ */
+ public static final SequenceElements synthesizeSequenceExpressionList(
+ EList<org.eclipse.papyrus.alf.alf.SequenceElement> seqElts){
+ SequenceExpressionList synthesized = null;
+ if(seqElts!=null){
+ synthesized = new SequenceExpressionList();
+ synthesized.element = new ArrayList<Expression>();
+ for(org.eclipse.papyrus.alf.alf.SequenceElement seqElt : seqElts){
+ /*1.1 If it is not an Expression it is a SequenceConstructionExpression*/
+ if(seqElt instanceof org.eclipse.papyrus.alf.alf.impl.SequenceConstructionExpressionImpl){
+ synthesized.element.add(ASTExpressionFactory.synthesizeSequenceConstructionExpression(
+ (org.eclipse.papyrus.alf.alf.SequenceConstructionExpression)seqElt));
+ }else{
+ synthesized.element.add(ASTExpressionFactory.synthesizeExpression(
+ (org.eclipse.papyrus.alf.alf.ConditionalTestExpression)seqElt));
+ }
+ }
+ //TODO : upper and lower must be computed
+ }
+ return synthesized;
+ }
+
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix SequenceOperationExpression
+ */
+ public static final Expression synthesizeSequenceOperationExpression(
+ Expression target, org.eclipse.papyrus.alf.alf.SequenceOperationExpression suffix) {
+ SequenceOperationExpression synthesized = new SequenceOperationExpression() ;
+
+ /*1. Synthesize property tuple:Tuple */
+ synthesized.tuple = ASTExpressionFactory.synthesizeTuple(suffix.getTuple(), synthesized) ;
+
+ /*2. Synthesize property associationName:QualifiedName */
+ synthesized.operation = ASTExpressionFactory.synthesizeQualifiedName(target) ;
+
+ if (suffix.getSuffix() != null) {
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+ }
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix SequenceReductionExpression
+ */
+ public static final Expression synthesizeSequenceReductionExpression(
+ Expression target, org.eclipse.papyrus.alf.alf.SequenceReductionExpression suffix) {
+ SequenceReductionExpression synthesized = new SequenceReductionExpression() ;
+
+ /*1. Synthesize property behaviorName:QualifiedName */
+ synthesized.behaviorName = ASTExpressionFactory.synthesizeQualifiedName(suffix.getBehavior()) ;
+
+ /*2. Synthesize property isOrdered:boolean */
+ synthesized.isOrdered = suffix.isIsOrdered() ;
+
+ /*3. Synthesize property primary:ExtentOrExpression */
+ synthesized.primary = ASTExpressionFactory.synthesizeExtentOrExpression(target) ;
+
+ if (suffix.getSuffix() != null) {
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+ }
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix SequenceExpansionExpression
+ */
+ public static final Expression synthesizeSequenceExpansionExpression(
+ Expression target, org.eclipse.papyrus.alf.alf.SequenceExpansionExpression suffix) {
+ if (suffix instanceof org.eclipse.papyrus.alf.alf.SelectOrRejectOperation) {
+ return ASTExpressionFactory.synthesizeSelectOrRejectExpression(target,
+ (org.eclipse.papyrus.alf.alf.SelectOrRejectOperation)suffix) ;
+ }
+ else if (suffix instanceof org.eclipse.papyrus.alf.alf.ForAllOrExistsOrOneOperation) {
+ return ASTExpressionFactory.synthesizeForAllOrExistsOrOneExpression(target,
+ (org.eclipse.papyrus.alf.alf.ForAllOrExistsOrOneOperation)suffix) ;
+ }
+ else if (suffix instanceof org.eclipse.papyrus.alf.alf.CollectOrIterateOperation) {
+ return ASTExpressionFactory.synthesizeCollectOrIterateExpression(target,
+ (org.eclipse.papyrus.alf.alf.CollectOrIterateOperation)suffix) ;
+ }
+ else { // instanceof org.eclipse.papyrus.alf.alf.IsUniqueOperation
+ return ASTExpressionFactory.synthesizeIsUniqueExpression(target,
+ (org.eclipse.papyrus.alf.alf.IsUniqueOperation)suffix) ;
+ }
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix SelectOrRejectExpression
+ */
+ public static final Expression synthesizeSelectOrRejectExpression(Expression target,
+ SelectOrRejectOperation suffix) {
+ SelectOrRejectExpression synthesized = new SelectOrRejectExpression() ;
+
+ /*1. Synthesize property argument:Expression */
+ synthesized.argument = ASTExpressionFactory.synthesizeExpression(suffix.getExpr());
+
+ /*2. Synthesize property operation:String */
+ switch (suffix.getOp()) {
+ case SELECT:
+ synthesized.operation = "select" ;
+ break;
+ case REJECT:
+ synthesized.operation = "reject" ;
+ break;
+ default:
+ break;
+ }
+
+ /*3. Synthesize property variable:String */
+ synthesized.variable = suffix.getName() ;
+
+ /*4. Synthesize property primary:ExtentOrExpression */
+ synthesized.primary = ASTExpressionFactory.synthesizeExtentOrExpression(target) ;
+
+ if (suffix.getSuffix() != null) {
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+ }
+ return synthesized;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix ForAllOrExistsOrOneExpression
+ */
+ public static final Expression synthesizeForAllOrExistsOrOneExpression(
+ Expression target, ForAllOrExistsOrOneOperation suffix) {
+ ForAllOrExistsOrOneExpression synthesized = new ForAllOrExistsOrOneExpression() ;
+
+ /*1. Synthesize property argument:Expression */
+ synthesized.argument = ASTExpressionFactory.synthesizeExpression(suffix.getExpr());
+
+ /*2. Synthesize property operation:String */
+ switch (suffix.getOp()) {
+ case EXISTS:
+ synthesized.operation = "exists" ;
+ break;
+ case FORALL:
+ synthesized.operation = "forAll" ;
+ break;
+ case ONE:
+ synthesized.operation = "one" ;
+ break;
+ default:
+ break;
+ }
+
+ /*3. Synthesize property variable:String */
+ synthesized.variable = suffix.getName() ;
+
+ /*4. Synthesize property primary:ExtentOrExpression */
+ synthesized.primary = ASTExpressionFactory.synthesizeExtentOrExpression(target) ;
+
+ if (suffix.getSuffix() != null) {
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+ }
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix ForAllOrExistsOrOneExpression
+ */
+ public static final Expression synthesizeCollectOrIterateExpression(Expression target,
+ CollectOrIterateOperation suffix) {
+ ForAllOrExistsOrOneExpression synthesized = new ForAllOrExistsOrOneExpression() ;
+
+ /*1. Synthesize property argument:Expression */
+ synthesized.argument = ASTExpressionFactory.synthesizeExpression(suffix.getExpr());
+
+ /*2. Synthesize property operation:String */
+ switch (suffix.getOp()) {
+ case COLLECT:
+ synthesized.operation = "collect" ;
+ break;
+ case ITERATE:
+ synthesized.operation = "iterate" ;
+ break;
+ default:
+ break;
+ }
+
+ /*3. Synthesize property variable:String */
+ synthesized.variable = suffix.getName() ;
+
+ /*4. Synthesize property primary:ExtentOrExpression */
+ synthesized.primary = ASTExpressionFactory.synthesizeExtentOrExpression(target) ;
+
+ if (suffix.getSuffix() != null) {
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+ }
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix IsUniqueExpression
+ */
+ public static final Expression synthesizeIsUniqueExpression(Expression target,
+ IsUniqueOperation suffix) {
+ IsUniqueExpression synthesized = new IsUniqueExpression() ;
+
+ /*1. Synthesize property argument:Expression */
+ synthesized.argument = ASTExpressionFactory.synthesizeExpression(suffix.getExpr());
+
+ /*2. Synthesize property variable:String */
+ synthesized.variable = suffix.getName() ;
+
+ /*3. Synthesize property primary:ExtentOrExpression */
+ synthesized.primary = ASTExpressionFactory.synthesizeExtentOrExpression(target) ;
+
+ if (suffix.getSuffix() != null) {
+ return ASTExpressionFactory.synthesizeExpression(synthesized, suffix.getSuffix()) ;
+ }
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.Expression from a alf.syntax.expressions.Expression
+ * and a suffix ClassExtentExpression
+ */
+ public static final Expression synthesizeClassExtentExpression(Expression target,
+ org.eclipse.papyrus.alf.alf.ClassExtentExpression suffix) {
+ ClassExtentExpression synthesized = new ClassExtentExpression() ;
+
+ /*1. Synthesize property className:QualifiedName */
+ synthesized.className = ASTExpressionFactory.synthesizeQualifiedName(target) ;
+
+ return synthesized ;
+ }
+
+ /*
+ * Synthesizes a alf.syntax.expressions.ExtentOrExpression
+ * from a alf.syntax.expressions.Expression
+ */
+ public static final ExtentOrExpression synthesizeExtentOrExpression(
+ Expression target) {
+ ExtentOrExpression synthesized = new ExtentOrExpression() ;
+
+ /* 1. Case where it is an Extent: Tries to synthesize property name:QualifiedName */
+ QualifiedName tryQualifiedName = ASTExpressionFactory.synthesizeQualifiedName(target) ;
+ if (tryQualifiedName.nameBinding != null &&
+ !tryQualifiedName.nameBinding.isEmpty()) {
+ synthesized.name = tryQualifiedName ;
+ }
+ else { // this is not an extent expression.
+ /* 2. Synthesize property nonNameExpression:Expression */
+ synthesized.nonNameExpression = target ;
+ }
+
+ return synthesized ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTStatementFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTStatementFactory.java new file mode 100644 index 00000000000..ea3af80ea22 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTStatementFactory.java @@ -0,0 +1,317 @@ +package org.eclipse.papyrus.alf.syntax;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+import org.eclipse.papyrus.alf.syntax.statements.AcceptBlock;
+import org.eclipse.papyrus.alf.syntax.statements.AcceptStatement;
+import org.eclipse.papyrus.alf.syntax.statements.Block;
+import org.eclipse.papyrus.alf.syntax.statements.ConcurrentClauses;
+import org.eclipse.papyrus.alf.syntax.statements.IfStatement;
+import org.eclipse.papyrus.alf.syntax.statements.LocalNameDeclarationStatement;
+import org.eclipse.papyrus.alf.syntax.statements.NonFinalClause;
+import org.eclipse.papyrus.alf.syntax.statements.QualifiedNameList;
+import org.eclipse.papyrus.alf.syntax.statements.Statement;
+import org.eclipse.papyrus.alf.syntax.statements.WhileStatement;
+
+public class ASTStatementFactory {
+
+ /**
+ * Build an alf.syntax.statements.Block from Block
+ * @param parsed
+ * @return alf.syntax.statements.Block
+ */
+ public static final Block synthesizeBlock(org.eclipse.papyrus.alf.alf.Block parsed){
+ Block synthesized = null;
+ if(parsed!=null){
+ synthesized = new Block();
+ /*1. Retrieve all statements*/
+ synthesized.statement = new ArrayList<Statement>();
+ if(parsed.getSequence()!=null){
+ org.eclipse.papyrus.alf.alf.StatementSequence seq = parsed.getSequence();
+ if(seq.getStatements() != null){
+ for(org.eclipse.papyrus.alf.alf.DocumentedStatement dst :seq.getStatements()){
+ synthesized.statement.add(
+ ASTStatementFactory.synthesizeStatement(dst));
+ }
+ }
+ }
+ //TODO AssignmentBefore and AssignmentAfter
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.Statement from DocumentedStatement
+ * @param stmt
+ * @return
+ */
+ public static final Statement synthesizeStatement(
+ org.eclipse.papyrus.alf.alf.DocumentedStatement docstmt){
+ org.eclipse.papyrus.alf.alf.Statement stmt = docstmt.getStatement();
+ Statement synthesized = null;
+ if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.AnnotatedStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.BlockStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.EmptyStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.LocalNameDeclarationStatementImpl){
+ synthesized = ASTStatementFactory.synthesizeLocalNameDeclarationStatement(
+ (org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement)stmt);
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.IfStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.SwitchStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.WhileStatementImpl){
+ synthesized = ASTStatementFactory.synthesizeWhileStatement(
+ (org.eclipse.papyrus.alf.alf.WhileStatement)stmt);
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.DoStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.ForStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.BreakStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.ReturnStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.AcceptStatementImpl){
+ synthesized = ASTStatementFactory.synthesizeAcceptStatement(
+ (org.eclipse.papyrus.alf.alf.AcceptStatement)stmt);
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.ClassifyStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.InvocationOrAssignementOrDeclarationStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.SuperInvocationStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.ThisInvocationStatementImpl){
+
+ }
+ else if(stmt instanceof org.eclipse.papyrus.alf.alf.impl.InstanceCreationInvocationStatementImpl){
+
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.AcceptStatement from an AcceptStatement
+ * @param accept
+ * @return The AcceptStatement
+ */
+ public static final AcceptStatement synthesizeAcceptStatement(org.eclipse.papyrus.alf.alf.AcceptStatement parsed){
+ AcceptStatement synthesized = null;
+ if(parsed != null){
+ synthesized = new AcceptStatement();
+ synthesized.acceptBlock = new ArrayList<AcceptBlock>();
+ /*1. Determine whether the accept is simple or compound*/
+ if(parsed.getCompoundAccept() != null){
+ synthesized.isSimple = false;
+ org.eclipse.papyrus.alf.alf.CompoundAcceptStatementCompletion accept = parsed.getCompoundAccept();
+ /*1.1 Retrieve the block of the top AcceptStatement*/
+ AcceptBlock tmpAcceptBlock = ASTStatementFactory.synthesizeAcceptBlock(parsed.getClause());
+ tmpAcceptBlock.block = ASTStatementFactory.synthesizeBlock(accept.getBlock());
+ synthesized.acceptBlock.add(tmpAcceptBlock);
+ /*1.2 Retrieve the list of AcceptBlock of the CompoundStatement*/
+ for(org.eclipse.papyrus.alf.alf.AcceptBlock block: accept.getAcceptBlock()){
+ synthesized.acceptBlock.add(ASTStatementFactory.synthesizeAcceptBlock(block));
+ }
+ }else{
+ synthesized.isSimple = true;
+ synthesized.acceptBlock.add(ASTStatementFactory.synthesizeAcceptBlock(parsed.getClause()));
+ }
+ /*3. Determine which behavior contains this AcceptStatement*/
+ //TODO Assign the ElementReference to the behavior attribute
+
+ /*4. Determine the context behavior*/
+ //TODO Assign the behavior attribute to the context behavior evaluation provided by AlfJavaValidator
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.AcceptBlock from an AcceptClause
+ * @param parsed
+ * @return The AcceptBlock
+ */
+ public static final AcceptBlock synthesizeAcceptBlock(org.eclipse.papyrus.alf.alf.AcceptClause parsed){
+ AcceptBlock synthesized = null;
+ if(parsed != null){
+ synthesized = new AcceptBlock();
+ /*1. Local name which holds the signal instance*/
+ synthesized.name = parsed.getName();
+ /*2. Retrieve the list of signal accepted by this AcceptBlock*/
+ if(parsed.getQualifiedNameList() != null){
+ synthesized.signalNames = new QualifiedNameList();
+ synthesized.signalNames.name = new ArrayList<QualifiedName>();
+ for(org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding sigName :
+ parsed.getQualifiedNameList().getQualifiedName()){
+ synthesized.signalNames.name.add(
+ ASTExpressionFactory.synthesizeQualifiedName(sigName));
+ }
+ }
+ /*3 Set up the element reference on the signal*/
+ //TODO Assign the ElementReference to the signal attribute
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.AcceptBlock from an AcceptBlock
+ * @param parsed
+ * @return The AcceptBlock
+ */
+ public static final AcceptBlock synthesizeAcceptBlock(org.eclipse.papyrus.alf.alf.AcceptBlock parsed){
+ AcceptBlock synthesized = null;
+ if(parsed!=null){
+ synthesized = ASTStatementFactory.synthesizeAcceptBlock(parsed.getClause());
+ synthesized.block = ASTStatementFactory.synthesizeBlock(parsed.getBlock());
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.LocalNameDeclarationStatement from an LocalNameDeclarationStatement
+ * @param parsed
+ * @return The LocalNameDeclarationStatement
+ */
+ public static final LocalNameDeclarationStatement synthesizeLocalNameDeclarationStatement(org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement parsed){
+ LocalNameDeclarationStatement synthesized = null;
+ if(parsed!=null){
+ synthesized = new LocalNameDeclarationStatement();
+ /*1. Determine if the multiplicity is specified*/
+ synthesized.hasMultiplicity = parsed.isMultiplicityIndicator();
+ /*2. Determine the name of the local name being declared*/
+ synthesized.name = parsed.getVarName();
+ /*3. Determine the type of the local name being declared*/
+ synthesized.typeName = ASTExpressionFactory.synthesizeQualifiedName(parsed.getType());
+ /*4 Build the expression to evaluated in order to provide the initial value*/
+ if(parsed.getInit() != null){
+ /*If it is not an Expression it is a SequenceConstructionExpression*/
+ if(parsed.getInit() instanceof
+ org.eclipse.papyrus.alf.alf.impl.SequenceConstructionExpressionImpl){
+ synthesized.expression = ASTExpressionFactory.synthesizeSequenceConstructionExpression(
+ (org.eclipse.papyrus.alf.alf.SequenceConstructionExpression)parsed.getInit());
+ }else{
+ synthesized.expression = ASTExpressionFactory.synthesizeExpression(
+ (org.eclipse.papyrus.alf.alf.ConditionalTestExpression)parsed.getInit());
+ }
+ }
+ /*5. type attribute should be assigned to an ElementReference referencing the type*/
+ if(synthesized.expression.type != null){
+ synthesized.type = synthesized.expression.type;
+ }
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.WhileStatement from an WhileStatement
+ * @param parsed
+ * @return The WhileStatement
+ */
+ public static final WhileStatement synthesizeWhileStatement(org.eclipse.papyrus.alf.alf.WhileStatement parsed){
+ WhileStatement synthesized = null;
+ if(parsed!=null){
+ /*Condition and Block shall be valid*/
+ if(parsed.getCondition() != null && parsed.getBlock() != null){
+ synthesized = new WhileStatement();
+ synthesized.condition = ASTExpressionFactory.synthesizeExpression(parsed.getCondition());
+ synthesized.body = ASTStatementFactory.synthesizeBlock(parsed.getBlock());
+ }
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.IfStatement from an IfStatement
+ * @param parsed
+ * @return The IfStatement
+ */
+ public static final IfStatement synthesizeIfStatement(org.eclipse.papyrus.alf.alf.IfStatement parsed){
+ IfStatement synthesized = null;
+ if(parsed!=null){
+ synthesized = new IfStatement();
+ synthesized.finalClause = ASTStatementFactory.synthesizeBlock(parsed.getFinalClause());
+ synthesized.nonFinalClauses = ASTStatementFactory.
+ synthesizeConcurrentClausesList(parsed.getSequentialClausses());
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.Block from a FinalClause
+ * @param parsed
+ * @return The Block
+ */
+ public static final Block synthesizeBlock(org.eclipse.papyrus.alf.alf.FinalClause parsed){
+ Block synthesized = null;
+ if(parsed!=null && parsed.getBlock()!=null){
+ synthesized = ASTStatementFactory.synthesizeBlock(parsed.getBlock());
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.NonFinalClause from a NonFinalClause
+ * @param parsed
+ * @return
+ */
+ public static final NonFinalClause synthesizeNonFinalClause(org.eclipse.papyrus.alf.alf.NonFinalClause parsed){
+ NonFinalClause synthesized = null;
+ if(parsed != null && (parsed.getBlock() != null && parsed.getCondition() != null)){
+ synthesized = new NonFinalClause();
+ synthesized.condition = ASTExpressionFactory.synthesizeExpression(parsed.getCondition());
+ synthesized.body = ASTStatementFactory.synthesizeBlock(parsed.getBlock());
+ }
+ return synthesized;
+ }
+
+ /**
+ * Build an alf.syntax.statements.ConcurrentClauses from a ConcurrentClauses
+ * @param parsed
+ * @return The ConcurrentClauses
+ */
+ public static final ConcurrentClauses synthesizeConcurrentClauses(org.eclipse.papyrus.alf.alf.ConcurrentClauses parsed){
+ ConcurrentClauses synthesized = null;
+ if(parsed!=null && parsed.getNonFinalClause().size() >= 1){
+ synthesized = new ConcurrentClauses();
+ synthesized.clause = new ArrayList<NonFinalClause>();
+ for(org.eclipse.papyrus.alf.alf.NonFinalClause nonFinalClause :parsed.getNonFinalClause()){
+ NonFinalClause clause = ASTStatementFactory.synthesizeNonFinalClause(nonFinalClause);
+ if(clause!=null){
+ synthesized.clause.add(clause);
+ }
+ }
+ }
+ return synthesized;
+ }
+
+ public static final List<ConcurrentClauses> synthesizeConcurrentClausesList(org.eclipse.papyrus.alf.alf.SequentialClauses parsed){
+ List<ConcurrentClauses> synthesized = null;
+ if(parsed!=null && parsed.getConccurentClauses().size()>=1){
+ synthesized = new ArrayList<ConcurrentClauses>();
+ for(org.eclipse.papyrus.alf.alf.ConcurrentClauses concClause: parsed.getConccurentClauses()){
+ ConcurrentClauses clause = ASTStatementFactory.synthesizeConcurrentClauses(concClause);
+ if(clause!=null){
+ synthesized.add(clause);
+ }
+ }
+ }
+ return synthesized;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTUnitFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTUnitFactory.java new file mode 100644 index 00000000000..70ca0ba8027 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/ASTUnitFactory.java @@ -0,0 +1,6 @@ +package org.eclipse.papyrus.alf.syntax;
+
+public class ASTUnitFactory {
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/AssignedSource.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/AssignedSource.java new file mode 100644 index 00000000000..05ec0a8ae30 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/AssignedSource.java @@ -0,0 +1,12 @@ +package org.eclipse.papyrus.alf.syntax.common;
+
+public class AssignedSource {
+
+ // Synthesized properties
+ protected int lower ;
+ protected String name ;
+ protected SyntaxElement source ;
+ protected ElementReference type ;
+ protected int upper ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/DocumentedElement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/DocumentedElement.java new file mode 100644 index 00000000000..d0be1aee192 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/DocumentedElement.java @@ -0,0 +1,9 @@ +package org.eclipse.papyrus.alf.syntax.common;
+
+import java.util.List;
+
+public abstract class DocumentedElement {
+
+ protected List<String> documentation ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/ElementReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/ElementReference.java new file mode 100644 index 00000000000..b106f9a261b --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/ElementReference.java @@ -0,0 +1,5 @@ +package org.eclipse.papyrus.alf.syntax.common;
+
+public abstract class ElementReference {
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/ExternalElementReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/ExternalElementReference.java new file mode 100644 index 00000000000..401e52affde --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/ExternalElementReference.java @@ -0,0 +1,10 @@ +package org.eclipse.papyrus.alf.syntax.common;
+
+import org.eclipse.uml2.uml.Element;
+
+public class ExternalElementReference extends ElementReference {
+
+ // Synthesized properties
+ protected Element element ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/InternalElementReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/InternalElementReference.java new file mode 100644 index 00000000000..2839da4a9f2 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/InternalElementReference.java @@ -0,0 +1,8 @@ +package org.eclipse.papyrus.alf.syntax.common;
+
+public class InternalElementReference extends ElementReference {
+
+ // Synthesized properties
+ protected SyntaxElement element ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/SyntaxElement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/SyntaxElement.java new file mode 100644 index 00000000000..4706a88b86c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/common/SyntaxElement.java @@ -0,0 +1,5 @@ +package org.eclipse.papyrus.alf.syntax.common;
+
+public abstract class SyntaxElement {
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ArithmeticExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ArithmeticExpression.java new file mode 100644 index 00000000000..47fd23784ee --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ArithmeticExpression.java @@ -0,0 +1,47 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class ArithmeticExpression extends BinaryExpression {
+
+ // derived properties
+ protected boolean isConcatenation ;
+
+ // constraints
+
+ /*
+ * An arithmetic expression is a string concatenation expression if its type is String.
+ */
+ protected void checkArithmeticExpressionIsConcatenationDerivation () {
+
+ }
+
+ /*
+ * An arithmetic expression has a multiplicity lower bound of 0 if the lower bound if either operand
+ * expression is 0 and 1 otherwise.
+ */
+ protected void checkArithmeticExpressionLowerDerivation () {
+
+ }
+
+ /*
+ * The operands of an arithmetic expression must both have type Integer, unless the operator is +, in which
+ * case they may also both have type String.
+ */
+ protected void checkArithmeticExpressionOperandTypes () {
+
+ }
+
+ /*
+ * The type of an arithmetic expression is the same as the type of its operands.
+ */
+ protected void checkArithmeticExpressionTypeDerivation () {
+
+ }
+
+ /*
+ * An arithmetic expression has a multiplicity upper bound of 1.
+ */
+ protected void checkArithmeticExpressionUpperDerivation () {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/AssignmentExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/AssignmentExpression.java new file mode 100644 index 00000000000..f0be211e824 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/AssignmentExpression.java @@ -0,0 +1,193 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class AssignmentExpression extends Expression {
+
+ // Synthesized Properties
+ protected LeftHandSide leftHandSide ;
+ protected String operator ;
+ protected Expression rightHandSide ;
+
+ // Derived Properties
+ protected AssignedSource assignment ;
+ protected Expression expression ;
+ protected ElementReference feature ;
+ protected boolean isArithmetic ;
+ protected boolean isBitStringConversion ;
+ protected boolean isCollectionConversion ;
+ protected boolean isDataValueUpdate ;
+ protected boolean isDefinition ;
+ protected boolean isFeature ;
+ protected boolean isIndexed ;
+ protected boolean isSimple ;
+
+ // Constraints
+
+ /*
+ * The new assigned source for an assignment to a local name is the assignment expression. If the
+ * assignment is a definition, then the type is given by the right hand side, the multiplicity upper bound is 1
+ * if the upper bound of the right hand side is 1 and otherwise * and the multiplicity lower bound is 0.
+ * Otherwise, the type and multiplicity are the same as the left hand side.
+ */
+ public void checkAssignmentExpressionAssignmentDerivation() {
+
+ }
+
+ /*
+ * The assigned source of a name before the right-hand side expression of an assignment expression is the
+ * same as the assigned source before the assignment expression. The assigned source of a name before the
+ * left-hand side is the assigned source after the right-hand side expression.
+ */
+ public void checkAssignmentExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * For a compound assignment, both the left-hand and right-hand sides must have a multiplicity upper
+ * bound of 1.
+ */
+ public void checkAssignmentExpressionCompoundAssignmentMultiplicityConformance () {
+
+ }
+
+ /*
+ * For a compound assignment, both the left-hand side and the right-hand side must have the same type,
+ * consistent with the arithmetic or logical operator used in the compound assignment operator.
+ */
+ public void checkAssignmentExpressionCompoundAssignmentTypeConformance () {
+
+ }
+
+ /*
+ * For a compound assignment, the effective expression is the left-hand side treated as a name expression,
+ * property access expression or sequence access expression, as appropriate for evaluation to obtain the
+ * original value to be updated.
+ */
+ public void checkAssignmentExpressionExpressionDerivation () {
+
+ }
+
+ /*
+ * If the left-hand side of an assignment expression is a feature, then the feature of the assignment is the
+ * referent of the left-hand side.
+ */
+ public void checkAssignmentExpressionFeatureDerivation () {
+
+ }
+
+ /*
+ * An assignment expression is an arithmetic assignment if its operator is a compound assignment operator
+ * for an arithmetic operation.
+ */
+ public void checkAssignmentExpressionIsArithmeticDerivation () {
+
+ }
+
+ /*
+ * An assignment requires BitString conversion if the type of the left-hand side is BitString and either the
+ * type of the right-hand side is Integer or collection conversion is required and the type of the right-hand
+ * side is a collection class whose argument type is Integer.
+ */
+ public void checkAssignmentExpressionIsBitStringConversionDerivation () {
+
+ }
+
+ /*
+ * An assignment requires collection conversion if the type of the right-hand side is a collection class and
+ * its multiplicity upper bound is 1, and the type of the left-hand side is not a collection class.
+ */
+ public void checkAssignmentExpressionIsCollectionConversionDerivation () {
+
+ }
+
+ /*
+ * An assignment expression is a data value update if its left hand side is an attribute of a data value held in
+ * a local name or parameter.
+ */
+ public void checkAssignmentExpressionIsDataValueUpdateDerivation () {
+
+ }
+
+ /*
+ * An assignment expression is a definition if it is a simple assignment and its left hand side is a local name
+ * for which there is no assignment before the expression.
+ */
+ public void checkAssignmentExpressionIsDefinitionDerivation () {
+
+ }
+
+ /*
+ * The left hand side of an assignment expression is a feature if it is a kind of FeatureLeftHandSide.
+ */
+ public void checkAssignmentExpressionIsFeatureDerivation () {
+
+ }
+
+ /*
+ * The left hand side of an assignment expression is indexed if it has an index.
+ */
+ public void checkAssignmentExpressionIsIndexedDerivation () {
+
+ }
+
+ /*
+ * An assignment expression is a simple assignment if the assignment operator is "=".
+ */
+ public void checkAssignmentExpressionIsSimpleDerivation () {
+
+ }
+
+ /*
+ * An assignment expression has the same multiplicity lower bound as its right-hand side expression.
+ */
+ public void checkAssignmentExpressionLowerDerivation () {
+
+ }
+
+ /*
+ * If the left-hand side of a simple assignment is not a new local name and the multiplicity upper bound of
+ * the left-hand side is less than or equal to 1, then the multiplicity upper bound of the right-hand side
+ * cannot be greater than that of the left-hand side.
+ */
+ public void checkAssignmentExpressionSimpleAssignmentMultiplicityConformance () {
+
+ }
+
+ /*
+ * If the left-hand side of a simple assignment is not a new local name, and the right-hand side is not null,
+ * then the left-hand side must either be untyped or have a type that conforms to the type of the right-hand
+ * side expression.
+ */
+ public void checkAssignmentExpressionSimpleAssignmentTypeConformance () {
+
+ }
+
+ /*
+ * An assignment expression has the same type as its right-hand side expression.
+ */
+ public void checkAssignmentExpressionTypeDerivation () {
+
+ }
+
+ /*
+ * An assignment expression has the same multiplicity upper bound as its right-hand side expression.
+ */
+ public void checkAssignmentExpressionUpperDerivation () {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * The assignments after an assignment expression are the assignments after the left-hand side, updated by
+ * the assignment from the assignment statement, if any.
+ */
+ public List<AssignedSource> updateAssignments ( ) {
+ return new ArrayList<AssignedSource>() ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BehaviorInvocationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BehaviorInvocationExpression.java new file mode 100644 index 00000000000..101ebea21c5 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BehaviorInvocationExpression.java @@ -0,0 +1,44 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class BehaviorInvocationExpression extends InvocationExpression {
+
+ //Synthesized Properties
+ protected QualifiedName target ;
+
+ // Constraints
+
+ /*
+ * An input argument expression must be assignable to its corresponding parameter. An output parameter
+ * must be assignable to its corresponding argument expression. (Note that this implies that the type of an
+ * argument expression for an inout parameter must be the same as the type of that parameter.)
+ */
+ public void checkBehaviorInvocationExpressionArgumentCompatibility () {
+
+ }
+
+ /*
+ * If the target qualified name disambiguates to a feature reference, then the feature of a behavior
+ * invocation expression is that feature reference.
+ */
+ public void checkBehaviorInvocationExpressionFeatureDerivation () {
+
+ }
+
+ /*
+ * If the target qualified name does not disambiguate to a feature reference, then it must resolve to a
+ * behavior or an association end. Otherwise it must resolve to a single feature referent according to the
+ * overloading resolution rules, unless it is an implicit destructor call (in which case it has no referent).
+ */
+ public void checkBehaviorInvocationExpressionReferentConstraint () {
+
+ }
+
+ /*
+ * The referent of a behavior invocation expression is the behavior named by the target or, if the target
+ * disambiguates to a feature reference, the operation or signal being invoked.
+ */
+ public void checkBehaviorInvocationExpressionReferentDerivation () {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BinaryExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BinaryExpression.java new file mode 100644 index 00000000000..a90f4a1c9fb --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BinaryExpression.java @@ -0,0 +1,52 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public abstract class BinaryExpression extends Expression {
+
+ // Synthesized Properties
+ public Expression operand1 ;
+ public Expression operand2 ;
+ public String operator ;
+
+ // Constraints
+
+ /*
+ * The assignments in the operand expressions of a binary expression must be valid (as determined by the
+ * validateAssignments helper operation).
+ */
+ public void checkBinaryExpressionOperandAssignments() {
+
+ }
+
+ /*
+ * The operands of a binary expression must both have a multiplicity upper bound of 1.
+ */
+ public void checkBinaryExpressionOperandMultiplicity() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * The assignments after a binary expression include all the assignments before the expression that are not
+ * reassigned in either operand expression, plus the new assignments from each of the operand expressions.
+ */
+ public List<AssignedSource> updateAssignments ( ) {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+ /*
+ * In general the assignments before the operand expressions of a binary expression are the same as those
+ * before the binary expression and, if an assignment for a name is changed in one operand expression,
+ * then the assignment for that name may not change in the other operand expression. (This is overridden
+ * for conditional logical expressions.)
+ */
+ public boolean validateAssignments ( ) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BitStringUnaryExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BitStringUnaryExpression.java new file mode 100644 index 00000000000..5f5fbb60a87 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BitStringUnaryExpression.java @@ -0,0 +1,47 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class BitStringUnaryExpression extends UnaryExpression {
+
+ // Derived Properties
+ protected boolean isBitStringConversion ;
+
+ // Constraints
+
+ /*
+ * BitString conversion is required if the operand expression of a BitString unary expression has type
+ * Integer.
+ */
+ public void checkBitStringUnaryExpresionIsBitStringConversionDerivation() {
+
+ }
+
+ /*
+ * A BitString unary expression has the same multiplicity lower bound as its operand expression.
+ */
+ public void checkBitStringUnaryExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operand expression of a BitString unary expression must have type BitString or Integer and a
+ * multiplicity upper bound of 1.
+ */
+ public void checkBitStringUnaryExpressionOperand() {
+
+ }
+
+ /*
+ * A BitString unary expression has type BitString.
+ */
+ public void checkBitStringUnaryExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A BitString unary expression has a multiplicity upper bound of 1.
+ */
+ public void checkBitStringUnaryExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BooleanLiteralExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BooleanLiteralExpression.java new file mode 100644 index 00000000000..b17f88b7fc5 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BooleanLiteralExpression.java @@ -0,0 +1,17 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class BooleanLiteralExpression extends LiteralExpression {
+
+ // Synthesized Properties
+ public String image ;
+
+ //Constraints
+
+ /*
+ * The type of a boolean literal expression is Boolean.
+ */
+ public void checkBooleanLiteralExpressionTypeDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BooleanUnaryExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BooleanUnaryExpression.java new file mode 100644 index 00000000000..9469986d775 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/BooleanUnaryExpression.java @@ -0,0 +1,36 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class BooleanUnaryExpression extends UnaryExpression {
+
+ // Constraints
+
+ /*
+ * A Boolean unary expression has the same multiplicity lower bound as its operand expression.
+ */
+ public void checkBooleanUnaryExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operand expression of a Boolean unary expression must have type Boolean and a multiplicity upper
+ * bound of 1.
+ */
+ public void checkBooleanUnaryExpressionOperand() {
+
+ }
+
+ /*
+ * A Boolean unary expression has type Boolean.
+ */
+ public void checkBooleanUnaryExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A Boolean unary expression has a multiplicity upper bound of 1.
+ */
+ public void checkBooleanUnaryExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/CastExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/CastExpression.java new file mode 100644 index 00000000000..8005c5e1b26 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/CastExpression.java @@ -0,0 +1,61 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public class CastExpression extends Expression {
+
+ // Synthesized Properties
+ public Expression operand ;
+ public QualifiedName typeName ;
+
+ // Constraints
+
+ /*
+ * The assignments before the operand of a cast expression are the same as those before the cast
+ * expression.
+ */
+ public void checkCastExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * A cast expression has a multiplicity lower bound of 0.
+ */
+ public void checkCastExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a cast expression is the referent of the given type name (if there is one).
+ */
+ public void checkCastExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * If the cast expression has a type name, then it must resolve to a classifier.
+ */
+ public void checkCastExpressionTypeResolution() {
+
+ }
+
+ /*
+ * A cast expression has a multiplicity upper bound that is the same as the upper bound of its operand
+ * expression.
+ */
+ public void checkCastExpressionUpperDerivation() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * The assignments after a cast expression are the same as those after its operand expression.
+ */
+ public List<AssignedSource> updateAssignments ( ) {
+ return new ArrayList<AssignedSource>() ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ClassExtentExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ClassExtentExpression.java new file mode 100644 index 00000000000..98b17e87f74 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ClassExtentExpression.java @@ -0,0 +1,36 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class ClassExtentExpression extends Expression {
+
+ //Synthesized Properties
+ public QualifiedName className ;
+
+ //Constraints
+ /*
+ * The given type name must resolve to a non-template class.
+ */
+ public void checkClassExtentExpressionExtentType() {
+
+ }
+
+ /*
+ * The multiplicity lower bound of a class extent expression is 0.
+ */
+ public void checkClassExtentExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a class extent expression is the given class.
+ */
+ public void checkClassExtentExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a class expression is *.
+ */
+ public void checkClassExtentExpressionUpperDerivation() {
+
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ClassificationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ClassificationExpression.java new file mode 100644 index 00000000000..5713d13c930 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ClassificationExpression.java @@ -0,0 +1,65 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class ClassificationExpression extends UnaryExpression {
+
+ // Synthesized Properties
+ public QualifiedName typeName ;
+
+ // Derived Properties
+ public boolean isDirect ;
+ public ElementReference referent ;
+
+ //Constraints
+ /*
+ * A classification expression is direct if its operator is "hastype".
+ */
+ public void checkClassificationExpressionIsDirectDerivation() {
+
+ }
+
+ /*
+ * A classification expression has a multiplicity lower bound that is the same as the lower bound of its
+ * operand expression.
+ */
+ public void checkClassificationExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operand expression of a classification expression must have a multiplicity upper bound of 1.
+ */
+ public void checkClassificationExpressionOperand() {
+
+ }
+
+ /*
+ * The referent of a classification expression is the classifier to which the type name resolves.
+ */
+ public void checkClassificationExpressionReferentDerivation() {
+
+ }
+
+ /*
+ * A classification expression has type Boolean.
+ */
+ public void checkClassificationExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The type name in a classification expression must resolve to a classifier.
+ */
+ public void checkClassificationExpressionTypeName() {
+
+ }
+
+ /*
+ * A classification expression has a multiplicity upper bound of 1.
+ */
+ public void checkClassificationExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/CollectOrIterateExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/CollectOrIterateExpression.java new file mode 100644 index 00000000000..19299e2d6d3 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/CollectOrIterateExpression.java @@ -0,0 +1,30 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class CollectOrIterateExpression extends SequenceExpansionExpression {
+
+ // Constraints
+
+ /*
+ * A collect or iterate expression has a multiplicity lower bound that is the product of the bounds of its
+ * primary and argument expressions.
+ */
+ public void checkCollectOrIterateExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * A collect or iterate expression has the same type as its argument expression.
+ */
+ public void checkCollectOrIterateExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A collect or iterate expression has a multiplicity upper bound that is the product of the bounds of its
+ * primary and argument expressions.
+ */
+ public void checkCollectOrIterateExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ConditionalLogicalExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ConditionalLogicalExpression.java new file mode 100644 index 00000000000..100b93ee5b4 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ConditionalLogicalExpression.java @@ -0,0 +1,63 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public class ConditionalLogicalExpression extends BinaryExpression {
+
+ // Constraints
+
+ /*
+ * A conditional logical expression has a multiplicity lower bound of 0 if the lower bound if either operand
+ * expression is 0 and 1 otherwise.
+ */
+ public void checkConditionalLogicalExpressionLower() {
+
+ }
+
+ /*
+ * The operands of a conditional logical expression must have type Boolean.
+ */
+ public void checkConditionalLogicalExpressionOperands() {
+
+ }
+
+ /*
+ * A conditional logical expression has type Boolean.
+ */
+ public void checkConditionalLogicalExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A conditional logical expression has a multiplicity upper bound of 1.
+ */
+ public void checkConditionalLogicalExpressionUpper() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * If a name has the same assigned source after the second operand expression as before it, then that is its
+ * assigned source after the conditional logical expression. If a name is unassigned before the second
+ * operand expression, then it is considered unassigned after the conditional logical expression, even if it
+ * has an assigned source after the second operand expression. Otherwise its assigned source after the
+ * conditional logical expression is the conditional logical expression itself.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+ /*
+ * The assignments before the first operand expression of a conditional logical expression are the same as
+ * those before the conditional logical expression. The assignments before the second operand expression
+ * are the same as those after the first operand expression.(non-Javadoc)
+ */
+ public boolean validateAssignments() {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ConditionalTestExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ConditionalTestExpression.java new file mode 100644 index 00000000000..22e450aa0c6 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ConditionalTestExpression.java @@ -0,0 +1,77 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public class ConditionalTestExpression extends Expression {
+
+ // Synthesized Properties
+ public Expression operand1 ;
+ public Expression operand2 ;
+ public Expression operand3 ;
+
+ // Constraints
+
+ /*
+ * If a name is unassigned after the first operand expression and has an assigned source after one of the
+ * other operand expression, then it must have an assigned source after both of those expressions.
+ */
+ public void checkConditionalTestExpressionAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the first operand expression of a conditional-test expression are the same as
+ * those before the conditional-test expression. The assignments before the second and third operand
+ * expressions are the same as those after the first operand expression.
+ */
+ public void checkConditionalTestExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * The first operand expression of a conditional-test expression must be of type Boolean and have a
+ * multiplicity upper bound of 1.
+ */
+ public void checkConditionalTestExpressionCondition() {
+
+ }
+
+ /*
+ * The multiplicity lower bound of a conditional-test operator expression is the minimum of the
+ * multiplicity lower bounds of its second and third operand expressions.
+ */
+ public void checkConditionalTestExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a conditional-test operator expression is the effective common ancestor (if one exists) of the
+ * types of its second and third operand expressions.
+ */
+ public void checkConditionalTestExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a conditional-test operator expression is the maximum of the
+ * multiplicity upper bounds of its second and third operand expressions.
+ */
+ public void checkConditionalTestExpressionUpperDerivation() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * Returns unchanged all assignments for local names that are not reassigned in either the second or third
+ * operand expressions. Any local names that have different assignments after the second and third operand
+ * expressions are adjusted to have the conditional-test expression as their assigned source.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/EqualityExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/EqualityExpression.java new file mode 100644 index 00000000000..580b05c8aac --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/EqualityExpression.java @@ -0,0 +1,38 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class EqualityExpression extends BinaryExpression {
+
+ // Derived Properties
+ public boolean isNegated ;
+
+ // Constraints
+
+ /*
+ * An equality expression is negated if its operator is "!=".
+ */
+ public void checkEqualityExpressionIsNegatedDerivation() {
+
+ }
+
+ /*
+ * An equality expression has a multiplicity lower bound of 1.
+ */
+ public void checkEqualityExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * An equality expression has type Boolean.
+ */
+ public void checkEqualityExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * An equality expression has a multiplicity upper bound of 1.
+ */
+ public void checkEqualityExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/Expression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/Expression.java new file mode 100644 index 00000000000..3bd6c4cd785 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/Expression.java @@ -0,0 +1,45 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class Expression extends SyntaxElement {
+
+ // Derived Properties
+ public List<AssignedSource> assignmentAfter ;
+ public List<AssignedSource> assignmentBefore ;
+ public int lower ;
+ public ElementReference type ;
+ public int upper ;
+
+ //Constraints
+
+ /*
+ * The assignments after an expression are given by the result of the updateAssignments helper operation.
+ */
+ public void checkExpressionAssignmentsAfterDerivation() {
+
+ }
+
+ /*
+ * No name may be assigned more than once before or after an expression.
+ */
+ public void checkExpressionUniqueAssignments() {
+
+ }
+
+ // Helper Operations
+ /*
+ * Returns the assignments from before this expression updated for any assignments made in the
+ expression. By default, this is the same set as the assignments before the expression. This operation is
+ redefined only in subclasses of Expression for kinds of expressions that make assignments.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ExtentOrExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ExtentOrExpression.java new file mode 100644 index 00000000000..58e11dfddf2 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ExtentOrExpression.java @@ -0,0 +1,24 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class ExtentOrExpression {
+
+ // Synthesized Properties
+ public QualifiedName name ;
+ public Expression nonNameExpression ;
+
+
+ //Derived Properties
+ public Expression expression ;
+
+ // Constraints
+
+ /*
+ * The effective expression for the target is the parsed primary expression, if the target is not a qualified
+ name, a name expression, if the target is a qualified name other than a class name, or a class extent
+ expression, if the target is the qualified name of a class.
+ */
+ public void checkExtentOrExpressionExpressionDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureInvocationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureInvocationExpression.java new file mode 100644 index 00000000000..5da7801e6dd --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureInvocationExpression.java @@ -0,0 +1,50 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class FeatureInvocationExpression extends InvocationExpression {
+
+ // Synthesized Properties
+ public FeatureReference target ;
+
+ // Constraints
+
+ /*
+ * An alternative constructor invocation may only occur in an expression statement as the first statement in
+ * the definition for the method of a constructor operation.
+ */
+ public void checkFeatureInvocationExpressionAlternativeConstructor() {
+
+ }
+
+ /*
+ * If a feature invocation expression has an explicit target, then that is its feature. Otherwise, it is an
+ * alternative constructor call with its feature determined implicitly.
+ */
+ public void checkFeatureInvocationExpressionFeatureDerivation() {
+
+ }
+
+ /*
+ * If there is no target feature expression, then the implicit feature with the same name as the target type
+ * must be a constructor.
+ */
+ public void checkFeatureInvocationExpressionImplicitAlternativeConstructor() {
+
+ }
+
+ /*
+ * If a feature invocation expression is an implicit object destruction, it has no referent. Otherwise, its
+ * referent is the referent of its feature.
+ */
+ public void checkFeatureInvocationExpressionReferentDerivation() {
+
+ }
+
+ /*
+ * If a feature invocation expression is not an implicit destructor call, then it must be possible to determine
+ * a single valid referent for it according to the overloading resolution rules.
+ */
+ public void checkFeatureInvocationExpressionReferentExists() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureLeftHandSide.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureLeftHandSide.java new file mode 100644 index 00000000000..a7f2e9c4533 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureLeftHandSide.java @@ -0,0 +1,42 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class FeatureLeftHandSide extends LeftHandSide {
+
+ // Synthesized Properties
+ public FeatureReference feature ;
+
+ // Constraints
+
+ /*
+ * The assignments after a feature left-hand side are the assignments after the expression of the feature
+ * reference or, if there is an index, those after the index expression.
+ */
+ public void checkFeatureLeftHandSideAssignmentAfterDerivation() {
+
+ }
+
+ /*
+ * The assignments before the expression of the feature reference of a feature left-hand side are the
+ * assignments before the feature left-hand side.
+ */
+ public void checkFeatureLeftHandSideAssignmentBeforeDerivation() {
+
+ }
+
+ /*
+ * If a feature left-hand side has an index, then the assignments before the index expression are the
+ * assignments after the expression of the feature reference.
+ */
+ public void checkFeatureLeftHandSideAssignmentsBefore() {
+
+ }
+
+ /*
+ * The expression of the feature reference of a feature left-hand side must have a multiplicity upper bound
+ * of 1.
+ */
+ public void checkFeatureLeftHandSideFeatureExpression() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureReference.java new file mode 100644 index 00000000000..840167f5912 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/FeatureReference.java @@ -0,0 +1,42 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class FeatureReference extends SyntaxElement {
+
+ // Synthesized Properties
+
+ /*
+ * The target expression.
+ */
+ public Expression expression ;
+
+ /*
+ * The name of the feature
+ */
+ public NameBinding nameBinding ;
+
+ //Derived Properties
+ public ElementReference referent ;
+
+ // Constraints
+
+ /*
+ * The features referenced by a feature reference include the features of the type of the target expression
+ * and the association ends of any binary associations whose opposite ends are typed by the type of the
+ * target expression.
+ */
+ public void checkFeatureReferenceReferentDerivation() {
+
+ }
+
+ /*
+ * The target expression of the feature reference may not be untyped, nor may it have a primitive or
+ * enumeration type.
+ */
+ public void checkFeatureReferenceTargetType() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ForAllOrExistsOrOneExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ForAllOrExistsOrOneExpression.java new file mode 100644 index 00000000000..cd4fd852ebb --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ForAllOrExistsOrOneExpression.java @@ -0,0 +1,36 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class ForAllOrExistsOrOneExpression extends SequenceExpansionExpression {
+
+ // Constraints
+
+ /*
+ * The argument of a forAll, exists or one expression must have type Boolean and a multiplicity upper
+ * bound of 1.
+ */
+ public void checkForAllOrExistOrOneExpressionArgument() {
+
+ }
+
+ /*
+ * A forAll, exists or one expression has a multiplicity lower bound of 1.
+ */
+ public void checkForAllOrExistOrOneExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * A forAll, exists or one expression has the type Boolean.
+ */
+ public void checkForAllOrExistOrOneExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A forAll, exists or one expression has a multiplicity upper bound of 1.
+ */
+ public void checkForAllOrExistOrOneExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IncrementOrDecrementExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IncrementOrDecrementExpression.java new file mode 100644 index 00000000000..edebf6a1a2a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IncrementOrDecrementExpression.java @@ -0,0 +1,119 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class IncrementOrDecrementExpression extends Expression {
+
+ // Synthesized Properties
+ public boolean isPrefix ;
+ public LeftHandSide operand ;
+
+ // Derived Properties
+ public AssignedSource assignment ;
+ public Expression expression ;
+ public ElementReference feature ;
+ public boolean isDataValueUpdate ;
+ public boolean isFeature ;
+ public boolean isIndexed ;
+
+ // Constraints
+
+ /*
+ * If the operand of an increment or decrement expression is a name, then the assignment for the
+ * expression is a new assigned source for the name with the expression as the source.
+ */
+ public void checkIncrementOrDecrementExpressionAssignment() {
+
+ }
+
+ /*
+ * The assignments before the operand of an increment or decrement expression are the same as those
+ * before the increment or decrement expression.
+ */
+ public void checkIncrementOrDecrementExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * The effective expression for the operand of an increment or decrement expression is the operand treated
+ * as a name expression, property access expression or sequence access expression, as appropriate for
+ * evaluation to obtain the original value to be updated.
+ */
+ public void checkIncrementOrDecrementExpressionExpressionDerivation() {
+
+ }
+
+ /*
+ * If the operand of an increment or decrement expression is a feature, then the referent for the operand.
+ */
+ public void checkIncrementOrDecrementExpressionFeature() {
+
+ }
+
+ /*
+ * An increment or decrement expression is a data value update if its operand is an attribute of a data value
+ * held in a local name or parameter.
+ */
+ public void checkIncrementOrDecrementExpressionIsDataValueUpdate() {
+
+ }
+
+ /*
+ * An increment or decrement expression has a feature as its operand if the operand is a kind of
+ * FeatureLeftHandSide.
+ */
+ public void checkIncrementOrDecrementExpressionIsFeatureDerivation() {
+
+ }
+
+ /*
+ * An increment or decrement expression is indexed if its operand is indexed.
+ */
+ public void checkIncrementOrDecrementExpressionIsIndexedDerivation() {
+
+ }
+
+ /*
+ * An increment or decrement expression has the same multiplicity lower bound as its operand expression.
+ */
+ public void checkIncrementOrDecrementExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operand expression must have type Integer and a multiplicity upper bound of 1.
+ */
+ public void checkIncrementOrDecrementExpressionOperand() {
+
+ }
+
+ /*
+ * An increment or decrement expression has type Integer.
+ */
+ public void checkIncrementOrDecrementExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * An increment or decrement expression has a multiplicity upper bound of 1.
+ */
+ public void checkIncrementOrDecrementExpressionUpperDerivation() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * The assignments after an increment and decrement expression include all those after its operand
+ * expression. Further, if the operand expression, considered as a left hand side, is a local name, then this is
+ * reassigned.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/InstanceCreationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/InstanceCreationExpression.java new file mode 100644 index 00000000000..85871b14ac5 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/InstanceCreationExpression.java @@ -0,0 +1,81 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class InstanceCreationExpression extends InvocationExpression {
+
+ // Synthesized Properties
+ public QualifiedName constructor ;
+
+ // Derived Properties
+ public boolean isConstructorless ;
+ public boolean isObjectCreation ;
+
+ // Constraints
+
+ /*
+ * The constructor name must resolve to a constructor operation (that is compatible with the tuple
+ * argument expressions), a class or a data type, but not both a class and a data type.
+ */
+ public void checkInstanceCreationExpressionConstructor() {
+
+ }
+
+ /*
+ * If an instance creation expression is a data value creation (not an object creation), then the tuple
+ * argument expressions are matched with the attributes of the named type.
+ */
+ public void checkInstanceCreationExpressionDataTypeCompatibility() {
+
+ }
+
+ /*
+ * There is no feature for an instance creation expression.
+ */
+ public void checkInstanceCreationExpressionFeatureDerivation() {
+
+ }
+
+ /*
+ * An instance creation expression is constructorless if its referent is a class.
+ */
+ public void checkInstanceCreationExpressionIsConstructorlessDerivation() {
+
+ }
+
+ /*
+ * An instance creation expression is an object creation if its referent is not a data type.
+ */
+ public void checkInstanceCreationExpressionIsObjectCreationDerivation() {
+
+ }
+
+ /*
+ * The referent of an instance creation expression is the constructor operation, class or data type to which
+ * the constructor name resolves.
+ */
+ public void checkInstanceCreationExpressionReferentDerivation() {
+
+ }
+
+ /*
+ * If the expression is constructorless, then its tuple must be empty.
+ */
+ public void checkInstanceCreationExpressionTuple() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * Returns the parameters of a constructor operation or the attributes of a data type, or an empty set for a
+ * constructorless instance creation.
+ */
+ public List<ElementReference> parameterElements ( ) {
+ return new ArrayList<ElementReference>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/InvocationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/InvocationExpression.java new file mode 100644 index 00000000000..1d837e8f9f1 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/InvocationExpression.java @@ -0,0 +1,132 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public abstract class InvocationExpression extends Expression {
+
+ // Synthesized Properties
+
+ /*
+ * The tuple for the invocation expression.
+ */
+ public Tuple tuple ;
+
+ // Derived Properties
+ public FeatureReference feature ;
+ public boolean isAssociationEnd ;
+ public boolean isBehavior ;
+ public boolean isDestructor ;
+ public boolean isImplicit ;
+ public boolean isOperation ;
+ public boolean isSignal ;
+ public List<ElementReference> parameter ;
+ public ElementReference referent ;
+
+ // Constraints
+
+ /*
+ * The assignments before the target expression of the feature reference of an invocation expression (if
+ * any) are the same as the assignments before the invocation expression.
+ */
+ public void checkInvocationExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * An invocation expression is an association end read if its referent is an association end.
+ */
+ public void checkInvocationExpressionIsAssociationEndDerivation() {
+
+ }
+
+ /*
+ * An invocation expression is a behavior invocation if its referent is a behavior.
+ */
+ public void checkInvocationExpressionIsBehaviorDerivation() {
+
+ }
+
+ /*
+ * An invocation expression is a destructor call either implicitly or if it is an explicit operation call to a
+ * destructor operation.
+ */
+ public void checkInvocationExpressionIsDestructorDerivation() {
+
+ }
+
+ /*
+ * An invocation expression is an implicit object destruction if it has a feature with the name "destroy" and
+ * no explicit referents.
+ */
+ public void checkInvocationExpressionIsImplicitDerivation() {
+
+ }
+
+ /*
+ * An invocation expression is an operation call if its referent is an operation.
+ */
+ public void checkInvocationExpressionIsOperationDerivation() {
+
+ }
+
+ /*
+ * An invocation expression is a signal send if its referent is a signal.
+ */
+ public void checkInvocationExpressionIsSignalDerivation() {
+
+ }
+
+ /*
+ * The multiplicity lower bound of an invocation expression is determined by the return parameter (if any)
+ * of the referent.
+ */
+ public void checkInvocationExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The parameters of an invocation expression are given by the result of the parameterElements helper
+ * operation.
+ */
+ public void checkInvocationExpressionParameterDerivation() {
+
+ }
+
+ /*
+ * The type of an invocation expression is determined by the return parameter (if any) of the referent.
+ */
+ public void checkInvocationExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of an invocation expression is determined by the return parameter (if any)
+ * of the referent.
+ */
+ public void checkInvocationExpressionUpperDerivation() {
+
+ }
+
+ // Helper Operations
+ /*
+ * Returns references to the elements that act as the parameters of the referent. For a behavior or operation,
+ * these are the owned parameters, in order. Otherwise (by default), they are actually any properties of the
+ * referent (e.g., signal attributes), which are treated as if they were in parameters. (This is defined as a
+ * helper operation, so that it can be overridden by subclasses of InvocationExpression, if necessary.)
+ */
+ public List<ElementReference>parameterElements() {
+ return new ArrayList<ElementReference>() ;
+ }
+
+ /*
+ * The assignments after an invocation expression are the same as those after the tuple of the expression.
+ */
+ public List<AssignedSource> updateAssignments ( ) {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IsUniqueExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IsUniqueExpression.java new file mode 100644 index 00000000000..010bc860880 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IsUniqueExpression.java @@ -0,0 +1,36 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class IsUniqueExpression extends SequenceExpansionExpression {
+
+ // Constraints
+
+ /*
+ * The argument of an isUnique expression must have a multiplicity upper bound of 1.
+ */
+ public void checkIsUniqueExpressionExpressionArgument() {
+
+ }
+
+ /*
+ * An isUnique expression has a multiplicity lower bound of 1.
+ */
+ public void checkIsUniqueExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * An isUnique expression has the type Boolean.
+ */
+ public void checkIsUniqueExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * An isUnique expression has a multiplicity upper bound of 1.
+ */
+ public void checkIsUniqueExpressionUpperDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IsolationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IsolationExpression.java new file mode 100644 index 00000000000..d4c101614ec --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/IsolationExpression.java @@ -0,0 +1,28 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class IsolationExpression extends UnaryExpression {
+
+ // Constraints
+
+ /*
+ * An isolation expression has the multiplicity lower bound of its operand expression.
+ */
+ public void checkIsolationExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * An isolation expression has the type of its operand expression.
+ */
+ public void checkIsolationExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * An isolation expression has the multiplicity upper bound of its operand expression.
+ */
+ public void checkIsolationExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LeftHandSide.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LeftHandSide.java new file mode 100644 index 00000000000..48096bfab2b --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LeftHandSide.java @@ -0,0 +1,24 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class LeftHandSide extends SyntaxElement {
+
+ // Derived Properties
+ public List<AssignedSource> assignmentAfter ;
+ public List<AssignedSource> assignmentBefore ;
+
+ // Constraints
+
+ /*
+ * If a left-hand side has an index, then the index expression must have a multiplicity upper bound no
+ * greater than 1.
+ */
+ public void checkLeftHandSideIndexExpression() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LinkOperationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LinkOperationExpression.java new file mode 100644 index 00000000000..9581d71bc4c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LinkOperationExpression.java @@ -0,0 +1,72 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class LinkOperationExpression extends InvocationExpression {
+
+ // Synthesized Properties
+ public QualifiedName associationName ;
+ public String operation ;
+
+ // Derived Properties
+ public boolean isClear ;
+ public boolean isCreation ;
+
+ // Constraints
+
+ /*
+ * Each argument expression must be assignable to its corresponding expression.
+ */
+ public void checkLinkOperationExpressionArgumentCompatibility() {
+
+ }
+
+ /*
+ * The qualified name of a link operation expression must resolve to a single association.
+ */
+ public void checkLinkOperationExpressionAssociationReference() {
+
+ }
+
+ /*
+ * There is no feature for a link operation expression.
+ */
+ public void checkLinkOperationExpressionFeatureDerivation() {
+
+ }
+
+ /*
+ * A link operation expression is for clearing an association if the operation is "clearAssoc".
+ */
+ public void checkLinkOperationExpressionIsClearDerivation() {
+
+ }
+
+ /*
+ * A link operation expression is for link creation if its operation is "createLink".
+ */
+ public void checkLinkOperationExpressionIsCreationDerivation() {
+
+ }
+
+ /*
+ * The referent for a link operation expression is the named association.
+ */
+ public void checkLinkOperationExpressionReferentDerivation() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * For a clear association operation, returns a single, typeless parameter. Otherwise, returns the ends of the
+ * named association.
+ */
+ public List<ElementReference> parameterElements() {
+ return new ArrayList<ElementReference>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LiteralExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LiteralExpression.java new file mode 100644 index 00000000000..2e6c91775c6 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LiteralExpression.java @@ -0,0 +1,28 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public abstract class LiteralExpression extends Expression {
+
+ // Constraints
+
+ /*
+ * The multiplicity lower bound of a literal expression is always 1.
+ */
+ public void checkLiteralExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a literal expression is given by the type of the literal, as defined for each subclass below.
+ */
+ public void checkLiteralExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a literal expression is always 1.
+ */
+ public void checkLiteralExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LogicalExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LogicalExpression.java new file mode 100644 index 00000000000..17b8f7af0a7 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/LogicalExpression.java @@ -0,0 +1,62 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class LogicalExpression extends BinaryExpression {
+
+ // Derived Properties
+ public boolean isBitStringConversion1 ;
+ public boolean isBitStringConversion2 ;
+ public boolean isBitWise ;
+
+ // Constraints
+
+ /*
+ * BitString conversion is required if the first operand expression of a shift expression has type Integer.
+ */
+ public void checkLogicalExpressionIsBitStringConversion1Derivation() {
+
+ }
+
+ /*
+ * BitString conversion is required if the second operand expression of a shift expression has type Integer.
+ */
+ public void checkLogicalExpressionIsBitStringConversion2Derivation() {
+
+ }
+
+ /*
+ * A logical expression is bit-wise if the type of its first operand is not Boolean.
+ */
+ public void checkLogicalExpressionIsBitWiseDerivation() {
+
+ }
+
+ /*
+ * A logical expression has a multiplicity lower bound of 0 if the lower bound if either operand expression
+ * is 0 and 1 otherwise.
+ */
+ public void checkLogicalExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operands of a logical expression must have type Boolean.
+ */
+ public void checkLogicalExpressionOperands() {
+
+ }
+
+ /*
+ * A logical expression has type Boolean.
+ */
+ public void checkLogicalExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A logical expression has a multiplicity upper bound of 1.
+ */
+ public void checkLogicalExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameBinding.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameBinding.java new file mode 100644 index 00000000000..d141f1fd766 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameBinding.java @@ -0,0 +1,11 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class NameBinding extends SyntaxElement {
+
+ // Synthesized Properties
+ public TemplateBinding binding ;
+ public String name ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameExpression.java new file mode 100644 index 00000000000..1bf8fc84c51 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameExpression.java @@ -0,0 +1,76 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class NameExpression extends Expression {
+
+ // Synthesized Properties
+ public QualifiedName name ;
+
+ // Derived Properties
+ public AssignedSource assignment ;
+ public ElementReference enumerationLiteral ;
+ public PropertyAccessExpression propertyAccess ;
+
+ // Constraints
+
+ /*
+ * If the name in a name expression is a local or parameter name, then its assignment is its assigned source
+ * before the expression.
+ */
+ public void checkNameExpressionAssignmentDerivation() {
+
+ }
+
+ /*
+ * If the name in a name expression resolves to an enumeration literal name, then that is the enumeration
+ * literal for the expression.
+ */
+ public void checkNameExpressionEnumerationLiteralDerivation() {
+
+ }
+
+ /*
+ * The multiplicity lower bound of a name expression is determined by its name.
+ */
+ public void checkNameExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * If the name in a name expression disambiguates to a feature reference, then the equivalent property
+ * access expression has the disambiguation of the name as its feature. The assignments before the property
+ * access expression are the same as those before the name expression.
+ */
+ public void checkNameExpressionPropertyAccessDerivation() {
+
+ }
+
+ /*
+ * If the name referenced by this expression is not a disambiguated feature reference or a local or
+ * parameter name, then it must resolve to exactly one enumeration literal.
+ */
+ public void checkNameExpressionResolution() {
+
+ }
+
+ /*
+ * The type of a name expression is determined by its name. If the name is a local name or parameter with
+ * an assignment, then the type of the name expression is the type of that assignment. If the name is an
+ * enumeration literal, then the type of the name expression is the corresponding enumeration. If the name
+ * disambiguates to a feature reference, then the type of the name expression is the type of the equivalent
+ * property access expression.
+ */
+ public void checkNameExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a name expression is determined by its name.
+ */
+ public void checkNameExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameLeftHandSide.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameLeftHandSide.java new file mode 100644 index 00000000000..57acdaed30a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NameLeftHandSide.java @@ -0,0 +1,34 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class NameLeftHandSide extends LeftHandSide {
+
+ // Synthesized Properties
+ public QualifiedName target ;
+
+ // Constraints
+
+ /*
+ * The assignments after a name left-hand side are the same as the assignments before.
+ */
+ public void checkNameLeftHandSideAssignmentAfterDerivation() {
+
+ }
+
+ /*
+ * If a name left-hand side has an index, then the target name must already have an assigned source and the
+ * assignments before the index expression are the assignments before the left-hand side.
+ */
+ public void checkNameLeftHandSideAssignmentsBefore() {
+
+ }
+
+ /*
+ * The target of a name left hand side may not already have an assigned source that is a loop variable
+ * definition, an annotation, a sequence expansion expression or a parameter that is an in parameter.
+ */
+ public void checkNameLeftHandSideTargetAssignment() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedExpression.java new file mode 100644 index 00000000000..13beb86f02a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedExpression.java @@ -0,0 +1,35 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class NamedExpression extends SyntaxElement {
+
+ // Synthesized Properties
+ public Expression expression ;
+ public Expression index ;
+ public String name ;
+
+ // Derived Properties
+ public boolean isBitStringConverstion ;
+ public boolean isCollectionConversion ;
+
+ // Constraints
+
+ /*
+ * Bit string conversion is required if the type of the type of the corresponding parameter is BitString, or a
+ * collection class instantiated with a BitString type, and the type of the argument expression is not
+ * BitString.
+ */
+ public void checkNamedExpressionIsBitStringConversionDerivation() {
+
+ }
+
+ /*
+ * Collection conversion is required if the type of the corresponding parameter is a collection class and the
+ * type of the argument expression is not.
+ */
+ public void checkNamedExpressionIsCollectionConversionDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedTemplateBinding.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedTemplateBinding.java new file mode 100644 index 00000000000..aa341350a8c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedTemplateBinding.java @@ -0,0 +1,9 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.List;
+
+public class NamedTemplateBinding extends TemplateBinding {
+
+ // Synthesized Properties
+ public List<TemplateParameterSubstitution> substitution ;
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedTuple.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedTuple.java new file mode 100644 index 00000000000..8228cd75bd7 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NamedTuple.java @@ -0,0 +1,10 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.List;
+
+public class NamedTuple extends Tuple {
+
+ // Synthesized Properties
+ public List<NamedExpression> namedExpression ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NaturalLiteralExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NaturalLiteralExpression.java new file mode 100644 index 00000000000..d5feab60555 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NaturalLiteralExpression.java @@ -0,0 +1,21 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class NaturalLiteralExpression extends LiteralExpression {
+
+ // Synthesized Properties
+ public String image ;
+
+ // Constraints
+
+ /*
+ * The type of a natural literal is the Alf library type Natural.
+ * NOTE: If the context of a natural literal expression unambiguously requires either an Integer or an
+ * UnlimitedNatural value, then the result of the literal expression is implicitly downcast to the required
+ * type. If the context is ambiguous, however, than an explicit cast to Integer or UnlimitedNatural must be
+ * used.
+ */
+ public void checkNaturalLiteralExpressionTypeDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NumericUnaryExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NumericUnaryExpression.java new file mode 100644 index 00000000000..e8d7d5d8212 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/NumericUnaryExpression.java @@ -0,0 +1,36 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class NumericUnaryExpression extends UnaryExpression {
+
+ // Constraints
+
+ /*
+ * A numeric unary expression has the same multiplicity lower bound as its operand expression.
+ */
+ public void checkNumericUnaryExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operand expression must have type Integer and a multiplicity upper bound of 1.
+ */
+ public void checkNumericUnaryExpressionOperand() {
+
+ }
+
+ /*
+ * A numeric unary expression must have type Integer.
+ */
+ public void checkNumericUnaryExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A numeric unary expression has a multiplicity upper bound of 1.
+ */
+ public void checkNumericUnaryExpressionUpperDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/OutputNamedExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/OutputNamedExpression.java new file mode 100644 index 00000000000..212c44c79d1 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/OutputNamedExpression.java @@ -0,0 +1,35 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class OutputNamedExpression extends NamedExpression {
+
+ // Derived Properties
+ public LeftHandSide leftHandSide ;
+
+ // Constraints
+
+ /*
+ * The argument for an output parameter must be either be null, a name expression, a property access
+ * expression, or a sequence access expression whose primary expression is a name expression or a
+ * property access expression.
+ */
+ public void checkOutputNamedExpressionForm() {
+
+ }
+
+ /*
+ * The equivalent left-hand side for an output named expression depends on the kind of expression. If the
+ * expression is a name expression with no disambiguation, then the left-hand side is a name left-hand side
+ * with the name from the name expression. If the expression is a name expression that disambiguates to a
+ * feature reference, then the left-hand side is a feature left-hand side for that feature reference. If the
+ * expression is a property access expression, then the left-hand side is a feature left-hand side for the
+ * feature reference of the property access expression. If the expression is a sequence access expression,
+ * then the left-hand side is a name left-hand side or feature left-hand side, as above, depending on whether
+ * the primary expression of the sequence access expression is a name expression or property access
+ * expression, and an index given by the index expression of the sequence access expression. Otherwise the
+ * left-hand side is empty.
+ */
+ public void checkOutputNamedExpressionLeftHandSideDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PositionalTemplateBinding.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PositionalTemplateBinding.java new file mode 100644 index 00000000000..7e3578f8a4c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PositionalTemplateBinding.java @@ -0,0 +1,8 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class PositionalTemplateBinding extends TemplateBinding {
+
+ // Synthesized Properties
+ public QualifiedName argumentName ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PositionalTuple.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PositionalTuple.java new file mode 100644 index 00000000000..7f8e5bff0cd --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PositionalTuple.java @@ -0,0 +1,10 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.List;
+
+public class PositionalTuple extends Tuple {
+
+ // Synthesized Properties
+ public List<Expression> expression ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PropertyAccessExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PropertyAccessExpression.java new file mode 100644 index 00000000000..5900ea68a59 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/PropertyAccessExpression.java @@ -0,0 +1,75 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class PropertyAccessExpression extends Expression {
+
+ // Synthesized Properties
+ public FeatureReference featureReference ;
+
+ // Derived Properties
+ public ElementReference feature ;
+
+ //Constraints
+
+ /*
+ * The assignments before the expression of the feature reference of a property access expression are the
+ * same as before the property access expression.
+ */
+ public void checkPropertyAccessExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * The feature of a property access expression is the structural feature to which its feature reference
+ * resolves.
+ */
+ public void checkPropertyAccessExpressionFeatureDerivation() {
+
+ }
+
+ /*
+ * The feature reference for a property access expression must resolve to a single structural feature.
+ */
+ public void checkPropertyAccessExpressionFeatureResolution() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a property access expression is given by the product of the multiplicity
+ * upper bounds of the referenced feature and the target expression.
+ */
+ public void checkPropertyAccessExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a property access expression is the type of the referenced feature.
+ */
+ public void checkPropertyAccessExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a property access expression is given by the product of the multiplicity
+ * upper bounds of the referenced feature and the target expression.
+ */
+ public void checkPropertyAccessExpressionUpperDerivation() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * The assignments after a property access expression are the same as those after the target expression of
+ * its feature reference.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/QualifiedName.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/QualifiedName.java new file mode 100644 index 00000000000..9c1d082b44a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/QualifiedName.java @@ -0,0 +1,198 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class QualifiedName extends SyntaxElement {
+
+ // Synthesized Properties
+
+ /*
+ * Whether this qualified name is ambiguous.
+ */
+ public boolean isAmbiguous = false ;
+
+ /*
+ * The sequence of individual name bindings in this qualified name.
+ */
+ public List<NameBinding> nameBinding ;
+
+ // Derived Properties
+
+ /*
+ * The disambiguation into a feature reference of a syntactic element initially parsed as a qualified
+ * name.
+ */
+ public FeatureReference disambiguation() {
+ // LIMITATION: The parser implementation only supports :: (no .)
+ // Therefore, a qualified name is never ambiguous
+ return null ;
+ }
+
+ /*
+ * Indicates whether this qualified name has been disambiguated to a feature reference.
+ */
+ public boolean isFeatureReference() {
+ // LIMITATION: The parser implementation only supports :: (no .)
+ // Therefore, a qualified name is never ambiguous
+ return false ;
+ }
+
+ /*
+ * The complete path name for the qualified name, with individual name bindings separated by "::"
+ * punctuation.
+ */
+ public String pathName() {
+ String path = "" ;
+ String doubleColon = "::" ;
+ boolean first = true ;
+ for (NameBinding n : this.nameBinding) {
+ path += (first ? "" : doubleColon) + n.name ;
+ if (first)
+ first = false ;
+ // TODO: Take into account template bindings
+ }
+ return path ;
+ }
+
+ /*
+ * The qualified name corresponding to the qualification part of this qualified name, if any.
+ */
+ public QualifiedName qualification() {
+ // TODO
+ return null ;
+ }
+
+ /*
+ * The possible referents to which this qualified name may resolve. (Note that the UML rules for
+ * namespaces in general allow a namespace to contain elements of different kinds with the same
+ * name.) If the qualified name is for a template instantiation, then the referent is the equivalent bound
+ * element.
+ */
+ public List<ElementReference> referent() {
+ // TODO
+ return new ArrayList<ElementReference>() ;
+ }
+
+
+ public QualifiedName templateName() {
+ // TODO
+ return null ;
+ }
+
+ /*
+ * The rightmost individual name binding in the qualified name, without the qualification.
+ */
+ public NameBinding unqualifiedName() {
+ // TODO
+ return null ;
+ }
+
+ //Constraints
+
+ /*
+ * If a qualified name is not ambiguous or it resolves to a namespace, then it is has no disambiguation.
+ * Otherwise, its disambiguation is a feature reference with a name given by the unqualified name of the
+ * qualified name and a target expression determined by the disambiguation of the qualification of the
+ * qualified name.
+ */
+ public void checkQualifiedNameDisambiguationDerivation() {
+
+ }
+
+ /*
+ * A qualified name is a feature reference is its disambiguation is not empty.
+ */
+ public void checkQualifiedNameIsFeatureReferenceDerivation() {
+
+ }
+
+ /*
+ * If a qualified name is a local name, then the reference must be within the same local scope as the
+ * definition of the named element.
+ */
+ public void checkQualifiedNameLocalName() {
+
+ }
+
+ /*
+ * If a qualified name is an unqualified, non-local name, then it must be visible in the current scope of the
+ * use of the name.
+ */
+ public void checkQualifiedNameNonLocalUnqualifiedName() {
+
+ }
+
+ /*
+ * The path name for a qualified name consists of the string representation of each of the name bindings,
+ * separated by "::" punctuation. The string representation of a name binding is its name followed by the
+ * representation of its template binding, if it has one. The string representation of a positional template
+ * binding consists of an ordered list of the path names of its argument qualified names separated by
+ * commas, all surrounded by the angle brackets "<" and ">". The string representation of a named
+ * template binding consists of an ordered list of its template parameter substitutions, each consisting of the
+ * formal parameter name followed by "=>" followed by the path name of the argument qualified name,
+ * separated by commas, all surrounded by the angle brackets "<" and ">".
+ */
+ public void checkQualifiedNamePathNameDerivation() {
+
+ }
+
+ /*
+ * The qualification of a qualified name is a empty if the qualified name has only one name binding.
+ * Otherwise it is the qualified name consisting of all the name bindings of the original qualified name
+ * except for the last one. The qualification of a qualified name is considered ambiguous if the qualified
+ * name is ambiguous and has more than two name bindings.
+ */
+ public void checkQualifiedNameQualificationDerivation() {
+
+ }
+
+ /*
+ * If a qualified name has a qualification, then its unqualified name must name an element of the
+ * namespace named by the qualification, where the first name in the qualification must name an element
+ * of the current scope.
+ */
+ public void checkQualifiedNameQualifiedResolution() {
+
+ }
+
+ /*
+ * The referents of a qualified name are the elements to which the name may resolve in the current scope,
+ * according to the UML rules for namespaces and named elements.
+ */
+ public void checkQualifiedNameReferentDerivation() {
+
+ }
+
+ /*
+ * If the unqualified name of a qualified name has a template binding, then the template name must resolve
+ * to a template. The template binding must have an argument name for each of the template parameters
+ * and each argument name must resolve to a classifier. If the template parameter has constraining
+ * classifiers, then the referent of the corresponding argument name must conform to all those constraining
+ * classifiers.
+ */
+ public void checkQualifiedNameTemplateBinding() {
+
+ }
+
+ /*
+ * If the last name binding in a qualified name has a template binding, then the template name is a qualified
+ * name with the same template bindings as the original qualified name, but with the template binding
+ * removed on the last name binding.
+ */
+ public void checkQualifiedNameTemplateNameDerivation() {
+
+ }
+
+ /*
+ * The unqualified name of a qualified name is the last name binding.
+ */
+ public void checkQualifiedNameUnqualifiedNameDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/RelationalExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/RelationalExpression.java new file mode 100644 index 00000000000..9b8b6b7eefe --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/RelationalExpression.java @@ -0,0 +1,50 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class RelationalExpression extends BinaryExpression {
+
+ // Derived Properties
+ public boolean isUnlimitedNatural ;
+
+ // Constraints
+
+ /*
+ * A relational expression has a multiplicity lower bound of 0 if the lower bound if either operand
+ * expression is 0 and 1 otherwise.
+ */
+ public void checkRelationalExpressionIsLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a relational expression is Boolean.
+ */
+ public void checkRelationalExpressionIsTypeDerivation() {
+
+ }
+
+ /*
+ * A relational expression is an UnlimitedNatural comparison if either one of its operands has type
+ * UnlimitedNatural.
+ */
+ public void checkRelationalExpressionIsUnlimitedNaturalDerivation() {
+
+ }
+
+ /*
+ * A relational expression has a multiplicity upper bound of 1.
+ */
+ public void checkRelationalExpressionIsUpperDerivation() {
+
+ }
+
+ /*
+ * The operand expressions for a comparison operator must have type Integer, UnlimitedNatural or
+ * Natural. However, it is not allowed to have one operand expression be Integer and the other be
+ * UnlimitedNatural.
+ */
+ public void checkRelationalExpressionOperandTypes() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SelectOrRejectExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SelectOrRejectExpression.java new file mode 100644 index 00000000000..a5d97ff873b --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SelectOrRejectExpression.java @@ -0,0 +1,37 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class SelectOrRejectExpression extends SequenceExpansionExpression {
+
+ // Constraints
+
+ /*
+ * The argument of a select or reject expression must have type Boolean and a multiplicity upper bound of
+ * 1.
+ */
+ public void checkSelectOrRejectExpressionArgument() {
+
+ }
+
+ /*
+ * A select or reject expression has a multiplicity lower bound of 0.
+ */
+ public void checkSelectOrRejectExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * A select or reject expression has the same type as its primary expression.
+ */
+ public void checkSelectOrRejectExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A select or reject expression has a multiplicity upper bound of *.
+ */
+ public void checkSelectOrRejectExpressionUpperDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceAccessExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceAccessExpression.java new file mode 100644 index 00000000000..4b2952dc6c2 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceAccessExpression.java @@ -0,0 +1,46 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class SequenceAccessExpression extends Expression {
+
+ // Synthesized Properties
+ public Expression index ;
+ public Expression primary ;
+
+ // Constraints
+
+ /*
+ * The multiplicity upper bound of the index of a sequence access expression must be 1.
+ */
+ public void checkSequenceAccessExpressionIndexMultiplicity() {
+
+ }
+
+ /*
+ * The type of the index of a sequence access expression must be Integer.
+ */
+ public void checkSequenceAccessExpressionIndexType() {
+
+ }
+
+ /*
+ * The multiplicity lower bound of a sequence access expression is 0.
+ */
+ public void checkSequenceAccessExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a sequence access expression is the same as the type of its primary expression.
+ */
+ public void checkSequenceAccessExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a sequence access expression is 1.
+ */
+ public void checkSequenceAccessExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceConstructionExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceConstructionExpression.java new file mode 100644 index 00000000000..36d84c7317c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceConstructionExpression.java @@ -0,0 +1,45 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class SequenceConstructionExpression extends Expression {
+
+ // Synthesized Properties
+ public SequenceElements elements ;
+ public boolean hasMultiplicity = false ;
+ public QualifiedName typeName ;
+
+ //Constraints
+
+ /*
+ * If a sequence construction expression has multiplicity, then its multiplicity lower bound is given by its
+ * elements, if this is not empty, and zero otherwise. If a sequence construction expression does not have
+ * multiplicity, then its multiplicity lower bound is one.
+ */
+ public void checkSequenceConstructionExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The type name of a sequence construction expression must resolve to a non-template classifier. If the
+ * expression does not have multiplicity, then this classifier must be the instantiation of a collection class.
+ */
+ public void checkSequenceConstructionExpressionType() {
+
+ }
+
+ /*
+ * The type of a sequence construction expression is the named type.
+ */
+ public void checkSequenceConstructionExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * If a sequence construction expression has multiplicity, then its multiplicity upper bound is given by its
+ * elements, if this is not empty, and zero otherwise. If a sequence construction expression does not have
+ * multiplicity, then its multiplicity upper bound is one.
+ */
+ public void checkSequenceConstructionExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceElements.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceElements.java new file mode 100644 index 00000000000..8988ff0f43a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceElements.java @@ -0,0 +1,11 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public abstract class SequenceElements extends SyntaxElement {
+
+ // Derived Properties
+ public int lower ;
+ public int upper ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceExpansionExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceExpansionExpression.java new file mode 100644 index 00000000000..ae1a653f14e --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceExpansionExpression.java @@ -0,0 +1,69 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public abstract class SequenceExpansionExpression extends Expression {
+
+ // Synthesized Properties
+ public Expression argument ;
+ public String operation ;
+ public ExtentOrExpression primary ;
+ public String variable ;
+
+ // Derived Properties
+ public AssignedSource variableSource ;
+
+ // Constraints
+
+ /*
+ * The assignments before the argument expression of a sequence expansion expression include those after
+ * the primary expression plus one for the expansion variable.
+ */
+ public void checkSequenceExpansionExpressionAssignmentsBeforeArgument() {
+
+ }
+
+ /*
+ * The assignments before the primary expression of a sequence expansion expression are the same as the
+ * assignments before the sequence expansion expression.
+ */
+ public void checkSequenceExpansionExpressionAssignmentsBeforePrimary() {
+
+ }
+
+ /*
+ * The expansion variable may not be assigned within the argument expression.
+ */
+ public void checkSequenceExpansionExpressionVariableAssignment() {
+
+ }
+
+ /*
+ * The expansion variable name may not conflict with any name already assigned after the primary
+ * expression.
+ */
+ public void checkSequenceExpansionExpressionVariableName() {
+
+ }
+
+ /*
+ * The assigned source for the expansion variable of a sequence expansion expression is the expression
+ * itself.
+ */
+ public void checkSequenceExpansionExpressionVariableSourceDerivation() {
+
+ }
+
+
+ //Helper Operations
+ /*
+ * The assignments after a sequence expansion expression are the same as after its primary expression.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceExpressionList.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceExpressionList.java new file mode 100644 index 00000000000..9532f7ac336 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceExpressionList.java @@ -0,0 +1,28 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.List;
+
+public class SequenceExpressionList extends SequenceElements {
+
+ // Synthesized Properties
+ public List<Expression> element ;
+
+ // Constraints
+ /*
+ * The multiplicity lower bound of the elements of a sequence expression list is given by the sum of the
+ * lower bounds of each of the expressions in the list.
+ */
+ public void checkSequenceExpressionListLowerDerivation() {
+
+ }
+
+ /*
+ * The multiplicity lower bound of the elements of a sequence expression list is given by the sum of the
+ * lower bounds of each of the expressions in the list. If any of the expressions in the list have an
+ * unbounded upper bound, then the sequence expression list also has an unbounded upper bound.
+ */
+ public void checkSequenceExpressionListUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceOperationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceOperationExpression.java new file mode 100644 index 00000000000..ecf06684668 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceOperationExpression.java @@ -0,0 +1,95 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public class SequenceOperationExpression extends InvocationExpression {
+
+ // Synthesized Properties
+ public QualifiedName operation ;
+ public ExtentOrExpression primary ;
+
+ // Derived Properties
+ public boolean isBitStringConversion ;
+ public boolean isCollectionConversion ;
+
+ // Constraints
+ /*
+ * The type of an input argument expression of a sequence operation parameter must be assignable to its
+ * corresponding parameter. The type of an output parameter must be assignable to its corresponding
+ * argument expression. (Note that this implies that the type of an argument expression for an inout
+ * parameter must be the same as the type of that parameter.)
+ */
+ public void checkSequenceOperationExpressionArgumentCompatibility() {
+
+ }
+
+ /*
+ * The assignments before the primary expression of a sequence operation expression are the same as the
+ * assignments before the sequence operation expression.
+ */
+ public void checkSequenceOperationExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * There is no feature for a sequence operation expression.
+ */
+ public void checkSequenceOperationExpressionFeatureDerivation() {
+
+ }
+
+ /*
+ * BitString conversion is required if type of the first parameter of the referent of a sequence operation
+ * expression is BitString and either the type of its primary expression is Integer or collection conversion is
+ * required and the type of its primary expression is a collection class whose argument type is Integer.
+ */
+ public void checkSequenceOperationExpressionIsBitStringConversionDerivation() {
+
+ }
+
+ /*
+ * Collection conversion is required if the type of the primary expression of a sequence operation
+ * expression is a collection class.
+ */
+ public void checkSequenceOperationExpressionIsCollectionConversionDerivation() {
+
+ }
+
+ /*
+ * There must be a single behavior that is a resolution of the operation qualified name of a sequence
+ * operation expression with a least one parameter, whose first parameter has direction in or inout, has
+ * multiplicity [0..*] and to which the target primary expression is assignable.
+ */
+ public void checkSequenceOperationExpressionOperationReferent() {
+
+ }
+
+ /*
+ * The referent for a sequence operation expression is the behavior named by the operation for the
+ * expression.
+ */
+ public void checkSequenceOperationExpressionReferentDerivation() {
+
+ }
+
+ /*
+ * If the first parameter of the referent has direction inout, then the parameter type must have the same type
+ as the primary expression.
+ */
+ public void checkSequenceOperationExpressionTargetCompatibility() {
+
+ }
+
+ //Helper Operations
+ /*
+ * The assignments after a sequence operation expression include those made in the primary expression
+ * and those made in the tuple and, for an "in place" operation (one whose first parameter is inout), that
+ * made by the sequence operation expression itself.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceRange.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceRange.java new file mode 100644 index 00000000000..ffcfa277489 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceRange.java @@ -0,0 +1,26 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class SequenceRange extends SequenceElements {
+
+ // Synthesized Properties
+ public Expression rangeLower ;
+ public Expression rangeUpper ;
+
+ // Constraints
+ /*
+ * The multiplicity lower bound of a sequence range is 0.
+ */
+ public void checkSequenceRangeLowerDerivation() {
+
+ }
+
+ /*
+ * The multiplicity uper bound of a sequence range is * (since it is not possible, in general, to statically
+ * determine a more constrained upper bound).
+ */
+ public void checkSequenceRangeUpperDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceReductionExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceReductionExpression.java new file mode 100644 index 00000000000..9ecb5a7a475 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SequenceReductionExpression.java @@ -0,0 +1,81 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class SequenceReductionExpression extends Expression {
+
+ // Synthesized Properties
+ public QualifiedName behaviorName ;
+ public boolean isOrdered = false ;
+ public ExtentOrExpression primary ;
+
+ // Derived Properties
+ public ElementReference referent ;
+
+ // Constraints
+ /*
+ * The assignments before the target expression of a sequence reduction expression are the same as the
+ * assignments before the sequence reduction expression.
+ */
+ public void checkSequenceReductionExpressionAssignmentsBefore() {
+
+ }
+
+ /*
+ * The behavior name in a sequence reduction expression must denote a behavior.
+ */
+ public void checkSequenceReductionExpressionBehavior() {
+
+ }
+
+ /*
+ * The referent behavior must have two in parameters, a return parameter and no other parameters. The
+ * parameters must all have the same type as the argument expression and multiplicity [1..1].
+ */
+ public void checkSequenceReductionExpressionBehaviorParameters() {
+
+ }
+
+ /*
+ * A sequence reduction expression has a multiplicity lower bound of 1.
+ */
+ public void checkSequenceReductionExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The referent for a sequence reduction expression is the behavior denoted by the behavior name of the
+ * expression.
+ */
+ public void checkSequenceReductionExpressionReferentDerivation() {
+
+ }
+
+ /*
+ * A sequence reduction expression has the same type as its primary expression.
+ */
+ public void checkSequenceReductionExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A sequence reduction expression has a multiplicity upper bound of 1.
+ */
+ public void checkSequenceReductionExpressionUpperDerivation() {
+
+ }
+
+
+ //Helper Operations
+ /*
+ * The assignments after a sequence reduction expression are the same as after its primary expression.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ShiftExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ShiftExpression.java new file mode 100644 index 00000000000..d842f546dea --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ShiftExpression.java @@ -0,0 +1,47 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class ShiftExpression extends BinaryExpression {
+
+ // Derived Properties
+ public boolean isBitStringConversion ;
+
+ // Constraints
+
+ /*
+ * BitString conversion is required if the first operand expression of a shift expression has type Integer.
+ */
+ public void checkShiftExpressionIsBitStringConversionDerivation() {
+
+ }
+
+ /*
+ * A shift expression has a multiplicity lower bound of 0 if the lower bound if either operand expression is
+ * 0 and 1 otherwise.
+ */
+ public void checkShiftExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The operands of a shift expression must have type BitString or Integer.
+ */
+ public void checkShiftExpressionOperands() {
+
+ }
+
+ /*
+ * A shift expression has type BitString.
+ */
+ public void checkShiftExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * A shift expression has a multiplicity upper bound of 1.
+ */
+ public void checkShiftExpressionUpperDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/StringLiteralExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/StringLiteralExpression.java new file mode 100644 index 00000000000..73f2cac34aa --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/StringLiteralExpression.java @@ -0,0 +1,18 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class StringLiteralExpression extends LiteralExpression {
+
+ //Synthesized Properties
+ public String image ;
+
+ //Constraints
+
+ /*
+ * The type of a string literal expression is String.
+ */
+ public void checkStringLiteralExpressionTypeDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SuperInvocationExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SuperInvocationExpression.java new file mode 100644 index 00000000000..d3dcc3cf744 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/SuperInvocationExpression.java @@ -0,0 +1,70 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class SuperInvocationExpression extends InvocationExpression {
+
+ // Synthesized Properties
+
+ /*
+ * The name of the operation to be invoked, optionally qualified with the name of the appropriate
+ * superclass.
+ */
+ public QualifiedName target ;
+
+ //Constraints
+
+ /*
+ * If the referent is the method of a constructor operation, the super invocation expression must occur in an
+ * expression statement at the start of the definition for the method of a constructor operation, such that any
+ * statements preceding it are also super constructor invocations.
+ */
+ public void checkSuperInvocationExpressionConstructorCall() {
+
+ }
+
+ /*
+ * If the referent is the method of a destructor operation, the super invocation expression must occur in an
+ * within the method of a destructor operation.
+ */
+ public void checkSuperInvocationExpressionDestructorCall() {
+
+ }
+
+ /*
+ * There is no feature for a super invocation.
+ */
+ public void checkSuperInvocationExpressionFeatureDerivation() {
+
+ }
+
+ /*
+ * If the target is empty, the referent must be the method for a constructor operation.
+ */
+ public void checkSuperInvocationExpressionImplicitTarget() {
+
+ }
+
+ /*
+ * It must be possible to identify a single valid operation denoted by the target of a super invocation
+ * expression that satisfies the overloading resolution rules.
+ */
+ public void checkSuperInvocationExpressionOperation() {
+
+ }
+
+ /*
+ * If the target has a qualification, then this must resolve to one of the superclasses of the current context
+ * class.
+ */
+ public void checkSuperInvocationExpressionQualification() {
+
+ }
+
+ /*
+ * The referent of a super invocation expression is the method behavior of the operation identified using
+ * the overloading resolution rules.
+ */
+ public void checkSuperInvocationExpressionReferentDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/TemplateBinding.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/TemplateBinding.java new file mode 100644 index 00000000000..bc078e5d970 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/TemplateBinding.java @@ -0,0 +1,7 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public abstract class TemplateBinding extends SyntaxElement {
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/TemplateParameterSubstitution.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/TemplateParameterSubstitution.java new file mode 100644 index 00000000000..bb0861e28cf --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/TemplateParameterSubstitution.java @@ -0,0 +1,11 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import org.eclipse.internal.xtend.expression.ast.SyntaxElement;
+
+public class TemplateParameterSubstitution extends SyntaxElement {
+
+ // Synthesized Properties
+ public QualifiedName argumentName ;
+ public String parameterName ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ThisExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ThisExpression.java new file mode 100644 index 00000000000..c7eced154ae --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/ThisExpression.java @@ -0,0 +1,28 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class ThisExpression extends Expression {
+
+ // Constraints
+ /*
+ * The multiplicity lower bound of a this expression is always 1.
+ */
+ public void checkThisExpressionLowerDerivation() {
+
+ }
+
+ /*
+ * The static type of a this expression is the statically determined context classifier for the context in which
+ * the this expression occurs.
+ */
+ public void checkThisExpressionTypeDerivation() {
+
+ }
+
+ /*
+ * The multiplicity upper bound of a this expression is always 1.
+ */
+ public void checkThisExpressionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/Tuple.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/Tuple.java new file mode 100644 index 00000000000..3ac95c8d06a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/Tuple.java @@ -0,0 +1,76 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public abstract class Tuple extends SyntaxElement {
+
+ // Synthesized Properties
+
+ /*
+ * The invocation expression of which this tuple is a part.
+ */
+ public InvocationExpression invocation ;
+
+ // Derived Properties
+ public List<NamedExpression> input ;
+ public List<OutputNamedExpression> output ;
+
+ // Constraints
+
+ /*
+ * A name may be assigned in at most one argument expression of a tuple.
+ */
+ public void checkTupleAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before each expression in a tuple are the same as the assignments before the tuple,
+ * except in the case of a name expression that defines a new local name, in which case the assigned source
+ * for the new name is included in the assignments before the name expression. (Note that the assigned
+ * source for a new name is included before the name expression so that the nameExpressionResolution
+ * constraint is not violated.) The assignments before the tuple are the same as the assignments after the
+ * feature reference of the invocation of the tuple, if the invocation has one, or otherwise the assignments
+ * before the invocation.
+ */
+ public void checkTupleAssignmentsBefore() {
+
+ }
+
+ /*
+ * A tuple has the same number of inputs as its invocation has input parameters. For each input parameter,
+ * the tuple has a corresponding input with the same name as the parameter and an expression that is the
+ * matching argument from the tuple, or an empty sequence construction expression if there is no matching
+ * argument.
+ */
+ public void checkTupleInputDerivation() {
+
+ }
+
+ /*
+ * An input parameter may only have a null argument if it has a multiplicity lower bound of 0.
+ */
+ public void checkTupleNullInputs() {
+
+ }
+
+ /*
+ * A tuple has the same number of outputs as its invocation has output parameters. For each output
+ * parameter, the tuple has a corresponding output with the same name as the parameter and an expression
+ * that is the matching argument from the tuple, or an empty sequence construction expression if there is no
+ * matching argument.
+ */
+ public void checkTupleOutputDerivation() {
+
+ }
+
+ /*
+ * An output parameter may only have a null argument if it is an out parameter.
+ */
+ public void checkTupleOutputs() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/UnaryExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/UnaryExpression.java new file mode 100644 index 00000000000..53e22260150 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/UnaryExpression.java @@ -0,0 +1,32 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+
+public class UnaryExpression extends Expression {
+
+ // Synthesized Properties
+ public Expression operand ;
+ public String operator ;
+
+ // Constraints
+
+ /*
+ * The assignments before the operand of a unary expression are the same as those before the unary
+ * expression.
+ */
+ public void checkUnaryExpressionAssignmentsBefore() {
+
+ }
+
+ //Helper Operations
+ /*
+ * By default, the assignments after a unary expression are the same as those after its operand expression.
+ */
+ public List<AssignedSource> updateAssignments() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/UnboundedLiteralExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/UnboundedLiteralExpression.java new file mode 100644 index 00000000000..decb332e203 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/expressions/UnboundedLiteralExpression.java @@ -0,0 +1,13 @@ +package org.eclipse.papyrus.alf.syntax.expressions;
+
+public class UnboundedLiteralExpression extends LiteralExpression {
+
+ // Constraints
+ /*
+ * The type of an unbounded literal expression is UnlimitedNatural.
+ */
+ public void checkUnboundedLiteralExpressionDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/AcceptBlock.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/AcceptBlock.java new file mode 100644 index 00000000000..3a3acfc6b90 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/AcceptBlock.java @@ -0,0 +1,35 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class AcceptBlock extends SyntaxElement {
+
+ // Synthesized Properties
+ public Block block ;
+ public String name ;
+ public QualifiedNameList signalNames ;
+
+ // Derived Properties
+ public List<ElementReference> signal ;
+
+ // Constraints
+
+ /*
+ * The signals of an accept block are the referents of the signal names of the accept block.
+ */
+ public void checkAcceptBlockSignalDerivation() {
+
+ }
+
+ /*
+ * All signal names in an accept block must resolve to signals.
+ */
+ public void checkAcceptBlockSignalNames() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/AcceptStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/AcceptStatement.java new file mode 100644 index 00000000000..b93fdbd69d9 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/AcceptStatement.java @@ -0,0 +1,102 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class AcceptStatement extends Statement {
+
+ // Synthesized Properties
+ public List<AcceptBlock> acceptBlock ;
+
+ // Derived Properties
+ public ElementReference behavior ;
+ public boolean isSimple ;
+
+ // Constraints
+
+ /*
+ * If a name is assigned in any block of an accept statement, then the assigned source of the name after the
+ * accept statement is the accept statement itself.
+ */
+ public void checkAcceptStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before any block of an accept statement are the assignments before the accept
+ * statement.
+ */
+ public void checkAcceptStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * For a compound accept statement, a local name defined in an accept block has the accept block as its
+ * assigned source before the block associated with the accept block. The type of the local name is the
+ * effective common ancestor of the specified signals for that accept clause, if one exists, and it is untyped
+ * otherwise. However, the local name is considered unassigned after the accept statement.
+ */
+ public void checkAcceptStatementCompoundAcceptLocalName() {
+
+ }
+
+ /*
+ * An accept statement can only be used within the definition of an active behavior or the classifier
+ * behavior of an active class.
+ */
+ public void checkAcceptStatementContext() {
+
+ }
+
+ /*
+ * The enclosing statement for all statements in the blocks of all accept blocks of an accept statement is the
+ * accept statement.
+ */
+ public void checkAcceptStatementEnclosedStatements() {
+
+ }
+
+ /*
+ * An accept statement is simple if it has exactly one accept block and that accept block does not have a
+ * block.
+ */
+ public void checkAcceptStatementIsSimpleDerivation() {
+
+ }
+
+ /*
+ * Any name defined in an accept block of an accept statement must be unassigned before the accept
+ * statement.
+ */
+ public void checkAcceptStatementNames() {
+
+ }
+
+ /*
+ * If a name is unassigned before an accept statement and assigned in any block of an accept statement,
+ * then it must be assigned in every block.
+ */
+ public void checkAcceptStatementNewAssignments() {
+
+ }
+
+ /*
+ * The containing behavior of an accept statement must have receptions for all signals from all accept
+ * blocks of the accept statement. No signal may be referenced in more than one accept block of an accept
+ * statement.
+ */
+ public void checkAcceptStatementSignals() {
+
+ }
+
+ /*
+ * A local name specified in the accept block of a simple accept statement has the accept statement as its
+ * assigned source after the accept statement. The type of the local name is the effective common ancestor
+ * of the specified signals, if one exists, and it is untyped otherwise.
+ */
+ public void checkAcceptStatementSimpleAcceptLocalName() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Annotation.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Annotation.java new file mode 100644 index 00000000000..455b116839c --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Annotation.java @@ -0,0 +1,13 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class Annotation extends SyntaxElement {
+
+ // Synthesized Properties
+ public List<String> argument ;
+ public String identifier ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Block.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Block.java new file mode 100644 index 00000000000..e19a31f72b6 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Block.java @@ -0,0 +1,36 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class Block extends SyntaxElement {
+
+ // Synthesized Properties
+ public List<Statement> statement ;
+
+ // Derived Properties
+ public List<AssignedSource> assignmentAfter ;
+ public List<AssignedSource> assignmentBefore ;
+
+ // Constraints
+
+ /*
+ * If a block is not empty, then the assignments after the block are the same as the assignments after the
+ * last statement of the block. Otherwise they are the same as the assignments before the block.
+ */
+ public void checkBlockAssignmentAfterDerivation() {
+
+ }
+
+ /*
+ * The assignments before each statement in a block other than the first are the same as the assignments
+ * after the previous statement.
+ */
+ public void checkBlockAssignmentsBeforeStatements() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/BlockStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/BlockStatement.java new file mode 100644 index 00000000000..c7ad3221848 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/BlockStatement.java @@ -0,0 +1,61 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+public class BlockStatement extends Statement {
+
+ // Synthesized Properties
+ public Block block ;
+
+ // Derived Properties
+ public boolean isParallel ;
+
+ // Constraints
+
+ /*
+ * The assignments after a block statement are the same as the assignments after the block of the block
+ * statement.
+ */
+ public void checkBlockStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the block of a block statement are the same as the assignments before the block
+ * statement.
+ */
+ public void checkBlockStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The enclosing statement for all the statements in the block of a block statement is the block statement.
+ */
+ public void checkBlockStatementEnclosedStatements() {
+
+ }
+
+ /*
+ * A block statement is parallel if it has a @parallel annotation.
+ */
+ public void checkBlockStatementIsParallelDerivation() {
+
+ }
+
+ /*
+ * In a parallel block statement, any name assigned in one statement of the block may not be further
+ * assigned in any subsequent statement in the same block.
+ */
+ public void checkBlockStatementParallelAssignments() {
+
+ }
+
+
+ // Helper Operations
+ /*
+ * In addition to an @isolated annotation, a block statement may have a @parallel annotation. It may not
+ have any arguments.
+ */
+ public boolean annotationAllowed (Annotation annotation ) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/BreakStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/BreakStatement.java new file mode 100644 index 00000000000..e60973c4262 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/BreakStatement.java @@ -0,0 +1,34 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+public class BreakStatement extends Statement {
+
+ // Derived Properties
+ public Statement target ;
+
+ // Constraints
+ /*
+ * The target of a break statement may not have a @parallel annotation.
+ */
+ public void checkBreakStatementNonparallelTarget() {
+
+ }
+
+ /*
+ * The target of a break statement is the innermost switch, while, do or for statement enclosing the break
+ * statement.
+ */
+ public void checkBreakStatementTargetDerivation() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * A break statement may not have any annotations.
+ */
+ public boolean annotationAllowed (Annotation annotation) {
+ return false ;
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ClassifyStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ClassifyStatement.java new file mode 100644 index 00000000000..43bfec48620 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ClassifyStatement.java @@ -0,0 +1,76 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class ClassifyStatement extends Statement {
+
+ // Synthesized Properties
+ public Expression expression ;
+ public QualifiedNameList fromList ;
+ public boolean isReclassifyAll = false ;
+ public QualifiedNameList toList ;
+
+ // Derived Properties
+ public List<ElementReference> fromClass ;
+ public List<ElementReference> toClass ;
+
+ // Constraints
+
+ /*
+ * The assignments after a classify statement are the same as the assignments after its expression.
+ */
+ public void checkClassifyStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the expression of a classify statement are the same as the assignments before the
+ * statement.
+ */
+ public void checkClassifyStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * All the from and to classes of a classify statement must be subclasses of the type of the target expression
+ * and none of them may have a common superclass that is a subclass of the type of the target expression
+ * (that is, they must be disjoint subclasses).
+ */
+ public void checkClassifyStatementClasses() {
+
+ }
+
+ /*
+ * All qualified names listed in the from or to lists of a classify statement must resolve to classes.
+ */
+ public void checkClassifyStatementClassNames() {
+
+ }
+
+ /*
+ * The expression in a classify statement must have a class as its type and multiplicity upper bound of 1.
+ */
+ public void checkClassifyStatementExpression() {
+
+ }
+
+ /*
+ * The from classes of a classify statement are the class referents of the qualified names in the from list for
+ * the statement.
+ */
+ public void checkClassifyStatementFromClassDerivation() {
+
+ }
+
+ /*
+ * The to classes of a classify statement are the class referents of the qualified names in the to list for the
+ * statement.
+ */
+ public void checkClassifyStatementToClassDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ConcurrentClauses.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ConcurrentClauses.java new file mode 100644 index 00000000000..50c436a71d9 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ConcurrentClauses.java @@ -0,0 +1,29 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class ConcurrentClauses extends SyntaxElement {
+
+ // Synthesized Properties
+ public List<NonFinalClause> clause ;
+
+ // Constraints
+ /*
+ * The assignments before each of the clauses in a set of concurrent clauses are the same as the
+ * assignments before the concurrent clauses.
+ */
+ public void checkConcurrentClausesAssignmentsBefore() {
+
+ }
+
+ /*
+ * The same name may not be assigned in more than one conditional expression within the same
+ * concurrent set of clauses.
+ */
+ public void checkConcurrentClausesConditionAssignments() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/DoStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/DoStatement.java new file mode 100644 index 00000000000..825ab1ab245 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/DoStatement.java @@ -0,0 +1,45 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class DoStatement extends Statement {
+
+ // Synthesized Properties
+ public Block body ;
+ public Expression condition ;
+
+ // Constraints
+
+ /*
+ * If the assigned source for a name after the condition expression is different than before the do statement,
+ * then the assigned source of the name after the do statement is the do statement. Otherwise it is the same
+ * as before the do statement.
+ */
+ public void checkDoStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the block of a do statement are the same as the assignments before the do
+ * statement. The assignments before the condition expression of a do statement are the same assignments
+ * after the block.
+ */
+ public void checkDoStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The condition expression of a do statement must have type Boolean and a multiplicity upper bound of 1.
+ */
+ public void checkDoStatementCondition() {
+
+ }
+
+ /*
+ * The enclosing statement for all statements in the body of a do statement are the do statement.
+ */
+ public void checkDoStatementEnclosedStatements() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/EmptyStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/EmptyStatement.java new file mode 100644 index 00000000000..d3a599ec31f --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/EmptyStatement.java @@ -0,0 +1,19 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+public class EmptyStatement extends Statement {
+
+ // Constraints
+
+ /*
+ * The assignments after and empty statement are the same as the assignments before the statement.
+ */
+ public void checkEmptyStatementAssignmentsAfter() {
+
+ }
+
+ // Helper Operations
+ public boolean annotationAllowed (Annotation annotation) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ExpressionStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ExpressionStatement.java new file mode 100644 index 00000000000..49a5f05cead --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ExpressionStatement.java @@ -0,0 +1,27 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class ExpressionStatement extends Statement {
+
+ // Synthesized Properties
+ public Expression expression ;
+
+ // Constraints
+
+ /*
+ * The assignments after an expression statement are the same as the assignments after its expression.
+ */
+ public void checkExpressionStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the expression of an expression statement are the same as the assignments
+ * before the statement.
+ */
+ public void checkExpressionStatementAssignmentsBefore() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ForStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ForStatement.java new file mode 100644 index 00000000000..c1e4d91cecd --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ForStatement.java @@ -0,0 +1,103 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+public class ForStatement extends Statement{
+
+ // Synthesized Properties
+ public Block body ;
+ public List<LoopVariableDefinition> variableDefinition ;
+
+ // Derived Properties
+ public boolean isParallel ;
+
+ // Constraints
+
+ /*
+ * The loop variables are unassigned after a for statement. Other than the loop variables, if the assigned
+ * source for a name after the body of a for statement is the same as after the for variable definitions, then
+ * the assigned source for the name after the for statement is the same as after the for variable definitions.
+ * If a name is unassigned after the for variable definitions, then it is unassigned after the for statement
+ * (even if it is assigned in the body of the for statement). If, after the loop variable definitions, a name has
+ * an assigned source, and it has a different assigned source after the body of the for statement, then the
+ * assigned source after the for statement is the for statement itself.
+ */
+ public void checkForStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before a loop variable definition in a for statement are the same as before the for
+ * statement. The assignments before the body of the statement include all the assignments before the
+ * statement plus any new assignments from the loop variable definitions, except that, if the statement is
+ * parallel, the assigned sources of any names given in @parallel annotations are changed to be the for
+ * statement itself.
+ */
+ public void checkForStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The enclosing statement for all statements in the body of a for statement are the for statement.
+ */
+ public void checkForStatementEnclosedStatements() {
+
+ }
+
+ /*
+ * A for statement is parallel if it has a @parallel annotation.
+ */
+ public void checkForStatementIsParallelDerivation() {
+
+ }
+
+ /*
+ * The assigned sources for loop variables after the body of a for statement must be the for statement (the
+ * same as before the body).
+ */
+ public void checkForStatementLoopVariables() {
+
+ }
+
+ /*
+ * A @parallel annotation of a for statement may include a list of names. Each such name must be already
+ * assigned after the loop variable definitions of the for statement, with a multiplicity of [0..*]. These
+ * names may only be used within the body of the for statement as the first argument to for the
+ * CollectionFunctions::add behavior.
+ */
+ public void checkForStatementParallelAnnotationNames() {
+
+ }
+
+ /*
+ * If, after the loop variable definitions of a parallel for statement, a name has an assigned source, then it
+ * must have the same assigned source after the block of the for statement. Other than for names defined in
+ * the @parallel annotation of the for statement, the assigned source for such names is the same after the
+ * for statement as before it. Any names defined in the @parallel annotation have the for statement itself as
+ * their assigned source after the for statement. Other than names given in the @parallel annotation, if a
+ * name is unassigned after the loop variable definitions, then it is considered unassigned after the for
+ * statement, even if it is assigned in the block of the for statement.
+ */
+ public void checkForStatementParallelAssignmentsAfter() {
+
+ }
+
+ /*
+ * The isFirst attribute of the first loop variable definition for a for statement is true while the isFirst
+ * attribute if false for any other definitions.
+ */
+ public void checkForStatementVariableDefinitions() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * In addition to an @isolated annotation, a for statement may have a @parallel annotation.
+ */
+ public boolean annotationAllowed (Annotation annotation) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/IfStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/IfStatement.java new file mode 100644 index 00000000000..e47e27665ab --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/IfStatement.java @@ -0,0 +1,74 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+public class IfStatement extends Statement {
+
+ // Synthesized Properties
+ public Block finalClause ;
+ public List<ConcurrentClauses> nonFinalClauses ;
+
+ // Derived Properties
+ public boolean isAssured ;
+ public boolean isDetermined ;
+
+ // Constraints
+
+ /*
+ * If an if statement does not have a final else clause, then any name that is unassigned before the if
+ * statement is unassigned after the if statement. If an if statement does have a final else clause, then any
+ * name that is unassigned before the if statement and is assigned after any one clause of the if statement
+ * must also be assigned after every other clause. The type of such names after the if statement is the
+ * effective common ancestor of the types of the name in each clause with a multiplicity lower bound that
+ * is the minimum of the lower bound for the name in each clause and a multiplicity upper bound that is the
+ * maximum for the name in each clause. For a name that has an assigned source after any clause of an if
+ * statement that is different than before that clause, then the assigned source after the if statement is the if
+ * statement. Otherwise, the assigned source of a name after the if statement is the same as before the if
+ * statement.
+ */
+ public void checkIfStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before all the non-final clauses of an if statement are the same as the assignments
+ * before the if statement. If the statement has a final clause, then the assignments before that clause are
+ * also the same as the assignments before the if statement.
+ */
+ public void checkIfStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The enclosing statement of all the statements in the bodies of all non-final clauses and in the final clause
+ * (if any) of an if statement is the if statement.
+ */
+ public void checkIfStatementEnclosedStatements() {
+
+ }
+
+ /*
+ * An if statement is assured if it has an @assured annotation.
+ */
+ public void checkIfStatementIsAssuredDerivation() {
+
+ }
+
+ /*
+ * An if statement is determined if it has an @determined annotation.
+ */
+ public void checkIfStatementIsDeterminedDerivation() {
+
+ }
+
+
+ // Helper Operations
+ /*
+ * In addition to an @isolated annotation, an if statement may have @assured and @determined
+ * annotations. They may not have arguments.
+ */
+ public boolean annotationAllowed (Annotation annotation) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/InLineStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/InLineStatement.java new file mode 100644 index 00000000000..69318c8c8e4 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/InLineStatement.java @@ -0,0 +1,19 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+public class InLineStatement extends Statement {
+
+ // Synthesized Properties
+ public String code ;
+ public String language ;
+
+ // Constraints
+
+ /*
+ * The assignments after an in-line statement are the same as the assignments before the statement.
+ */
+ public void checkInLineStatementAssignmentsAfter() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/LocalNameDeclarationStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/LocalNameDeclarationStatement.java new file mode 100644 index 00000000000..928eaad5f0b --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/LocalNameDeclarationStatement.java @@ -0,0 +1,70 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class LocalNameDeclarationStatement extends Statement {
+
+ // Synthesized Properties
+ public Expression expression ;
+ public boolean hasMultiplicity = false ;
+ public String name ;
+ public QualifiedName typeName ;
+
+ // Derived Properties
+ public ElementReference type ;
+
+ // Constraints
+ /*
+ * The assignments after a local name declaration statement are the assignments before the statement plus a
+ * new assignment for the local name defined by the statement. The assigned source for the local name is
+ * the local name declaration statement. The local name has the type denoted by the type name if this is not
+ * empty and is untyped otherwise. If the statement has multiplicity, then the multiplicity of the local name
+ * is [0..*], otherwise it is [0..1].
+ */
+ public void checkLocalNameDeclarationStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the expression of a local name declaration statement are the same as the
+ * assignments before the statement.
+ */
+ public void checkLocalNameDeclarationStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * If a local name declaration statement does not have multiplicity, then the multiplicity of upper bound of
+ * the assigned expression must not be greater than 1.
+ */
+ public void checkLocalNameDeclarationStatementExpressionMultiplicity() {
+
+ }
+
+ /*
+ * The local name in a local name declaration statement must be unassigned before the statement and
+ * before the expression in the statement. It must remain unassigned after the expression.
+ */
+ public void checkLocalNameDeclarationStatementLocalName() {
+
+ }
+
+ /*
+ * If the type name in a local name declaration statement is not empty, then it must resolve to a nontemplate
+ * classifier and the expression must be assignable to that classifier.
+ */
+ public void checkLocalNameDeclarationStatementType() {
+
+ }
+
+ /*
+ * The type of a local name declaration statement with a type name is the single classifier referent of the
+ * type name. Otherwise it is the type of the expression of the statement.
+ */
+ public void checkLocalNameDeclarationStatementTypeDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/LoopVariableDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/LoopVariableDefinition.java new file mode 100644 index 00000000000..a68fa33b710 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/LoopVariableDefinition.java @@ -0,0 +1,100 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class LoopVariableDefinition extends SyntaxElement{
+
+ // Synthesized Properties
+ public Expression expression1 ;
+ public Expression expression2 ;
+ public boolean typeIsInferred = true ;
+ public QualifiedName typeName ;
+ public String variable ;
+
+ // Derived Properties
+ public List<AssignedSource> assignmentAfter ;
+ public List<AssignedSource> assignmentBefore ;
+ public boolean isCollectionConversion ;
+ public boolean isFirst ;
+ public ElementReference type ;
+
+ // Constraints
+
+ /*
+ * The assignments after a loop variable definition include the assignments after the expression (or
+ * expressions) of the definition plus a new assigned source for the loop variable itself. The assigned
+ * source for the loop variable is the loop variable definition. The multiplicity upper bound for the variable
+ * is 1. The multiplicity lower bound is 1 if the loop variable definition is the first in a for statement and 0
+ * otherwise. If collection conversion is not required, then the variable has the inferred or declared type
+ * from the definition. If collection conversion is required, then the variable has the argument type of the
+ * collection class.
+ */
+ public void checkLoopVariableDefinitionAssignmentAfterDerivation() {
+
+ }
+
+ /*
+ * The assignments before the expressions of a loop variable definition are the assignments before the loop
+ * variable definition.
+ */
+ public void checkLoopVariableDefinitionAssignmentsBefore() {
+
+ }
+
+ /*
+ * If the type of a loop variable definition is not inferred, then the first expression of the definition must
+ * have a type that conforms to the declared type.
+ */
+ public void checkLoopVariableDefinitionDeclaredType() {
+
+ }
+
+ /*
+ * If a loop variable definition has two expressions, then both expressions must have type Integer and a
+ * multiplicity upper bound of 1, and no name may be newly assigned or reassigned in more than one of
+ * the expressions.
+ */
+ public void checkLoopVariableDefinitionRangeExpressions() {
+
+ }
+
+ /*
+ * If the type of a loop variable is not inferred, then the variable has the type denoted by the type name, if it
+ * is not empty, and is untyped otherwise. If the type is inferred, them the variable has the same as the type
+ * of the expression in its definition.
+ */
+ public void checkLoopVariableDefinitionTypeDerivation() {
+
+ }
+
+ /*
+ * If a loop variable definition has a type name, then this name must resolve to a non-template classifier.
+ */
+ public void checkLoopVariableDefinitionTypeName() {
+
+ }
+
+ /*
+ * The variable name given in a loop variable definition must be unassigned after the expression or
+ * expressions in the definition.
+ */
+ public void checkLoopVariableDefinitionVariable() {
+
+ }
+
+ /*
+ * Collection conversion is required for a loop variable definition if the type for the definition is the
+ * instantiation of a collection class and the multiplicity upper bound of the first expression is no greater
+ * than 1.
+ */
+ public void checkLoopVariableIsCollectionConversionDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/NonFinalClause.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/NonFinalClause.java new file mode 100644 index 00000000000..dce8a9c2ee9 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/NonFinalClause.java @@ -0,0 +1,58 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class NonFinalClause extends SyntaxElement {
+
+ // Synthesized Properties
+ public Block body ;
+ public Expression condition ;
+
+ // Constraints
+
+ /*
+ * The assignments before the body of a non-final clause are the assignments after the condition.
+ */
+ public void checkNonFinalClauseAssignmentsBeforeBody() {
+
+ }
+
+ /*
+ * If a name is unassigned before the condition expression of a non-final clause, then it must be unassigned
+ * after that expression (i.e., new local names may not be defined in the condition).
+ */
+ public void checkNonFinalClauseConditionLocalNames() {
+
+ }
+
+ /*
+ * The condition of a non-final clause must have type Boolean and a multiplicity upper bound no greater
+ * than 1.
+ */
+ public void checkNonFinalClauseConditionType() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * The assignments after a non-final clause are the assignments after the block of the clause.
+ */
+ public List<AssignedSource> assignmentsAfter() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+ /*
+ * The assignments before a non-final clause are the assignments before the condition of the clause.
+ */
+ public List<AssignedSource> assignmentsBefore() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/QualifiedNameList.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/QualifiedNameList.java new file mode 100644 index 00000000000..8d8426009cb --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/QualifiedNameList.java @@ -0,0 +1,13 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class QualifiedNameList extends SyntaxElement {
+
+ // Synthesized Properties
+ public List<QualifiedName> name ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ReturnStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ReturnStatement.java new file mode 100644 index 00000000000..479ab9b12cc --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/ReturnStatement.java @@ -0,0 +1,41 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class ReturnStatement extends Statement {
+
+ // Synthesized Properties
+ public Expression expression ;
+
+ // Derived Properties
+ public ElementReference behavior ;
+
+ // Constraints
+
+ /*
+ * The assignments after a return statement are the same as the assignments after the expression of the
+ * return statement.
+ */
+ public void checkReturnStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the expression of a return statement are the same as the assignments before the
+ * statement.
+ */
+ public void checkReturnStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The behavior containing the return statement must have a return parameter. The expression of the return
+ * statement must be assignable to that return parameter.
+ */
+ public void checkReturnStatementContext() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Statement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Statement.java new file mode 100644 index 00000000000..3ef3309ec85 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/Statement.java @@ -0,0 +1,55 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.DocumentedElement;
+
+public abstract class Statement extends DocumentedElement{
+
+ // Synthesized Properties
+ public List<Annotation> annotation ;
+
+ // Derived Properties
+ public List<AssignedSource> assignmentAfter ;
+ public List<AssignedSource> assignmentBefore ;
+ public Statement enclosingStatement ;
+ public boolean isIsolated ;
+
+ // Constraints
+
+ /*
+ * All the annotations of a statement must be allowed, as given by the annotationAllowed operation for the
+ * statement.
+ */
+ public void checkStatementAnnotationsAllowed() {
+
+ }
+
+ /*
+ * A statement is isolated if it has an @isolated annotation.
+ */
+ public void checkStatementIsIsolatedDerivation() {
+
+ }
+
+ /*
+ * No name may be assigned more than once before or after a statement.
+ */
+ public void checkStatementUniqueAssignments() {
+
+ }
+
+
+ //Helper Operations
+
+ /*
+ * Returns true if the given annotation is allowed for this kind of statement. By default, only an @isolated
+ * annotation is allowed, with no arguments. This operation is redefined only in subclasses of Statement for
+ * kinds of statements that allow different annotations than this default.
+ */
+ public boolean annotationAllowed(Annotation annotation) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/SwitchClause.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/SwitchClause.java new file mode 100644 index 00000000000..29a4e0dd451 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/SwitchClause.java @@ -0,0 +1,52 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.AssignedSource;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class SwitchClause extends SyntaxElement {
+
+ // Synthesized Properties
+ public Block block ;
+ public List<Expression> _case ;
+
+ // Constraints
+
+ /*
+ * The assignments before any case expression of a switch clause are the same as the assignments before
+ * the clause. The assignments before the block of a switch clause are the assignments after all case
+ * expressions.
+ */
+ public void checkSwitchClauseAssignmentsBefore() {
+
+ }
+
+ /*
+ * If a name is unassigned before a switch clause, then it must be unassigned after all case expressions of
+ * the clause (i.e., new local names may not be defined in case expressions).
+ */
+ public void checkSwitchClauseCaseLocalNames() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * The assignments after a switch clause are the assignments after the block of the switch clause.
+ */
+ public List<AssignedSource> assignmentsAfter() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+ /*
+ * The assignments before a switch clause are the assignments before any case expression of the clause.
+ */
+ public List<AssignedSource> assignmentsBefore() {
+ return new ArrayList<AssignedSource>() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/SwitchStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/SwitchStatement.java new file mode 100644 index 00000000000..f0c465e99f8 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/SwitchStatement.java @@ -0,0 +1,92 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class SwitchStatement extends Statement {
+
+ // Synthesized Properties
+ public Block defaultClause ;
+ public Expression expression ;
+ public List<SwitchClause> nonDefaultClause ;
+
+ // Derived Properties
+ public boolean isAssured ;
+ public boolean isDetermined ;
+
+ // Constraints
+
+ /*
+ * If a switch statement does not have a final default clause, then any name that is unassigned before the
+ * switch statement is unassigned after the switch statement. If a switch statement does have a final default
+ * clause, then any name that is unassigned before the switch statement and is assigned after any one clause
+ * of the switch statement must also be assigned after every other clause. The type of such names after the
+ * switch statement is the effective common ancestor of the types of the name in each clause with a
+ * multiplicity lower bound that is the minimum of the lower bound for the name in each clause and a
+ * multiplicity upper bound that is the maximum for the name in each clause.
+ */
+ public void checkSwitchStatementAssignments() {
+
+ }
+
+ /*
+ * If a name has an assigned source after any clause of a switch statement that is different than before that
+ * clause (including newly defined names), the assigned source after the switch statement is the switch
+ * statement. Otherwise, the assigned source of a name after the switch statement is the same as before the
+ * switch statement.
+ */
+ public void checkSwitchStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before all clauses of a switch statement are the same as the assignments before the
+ * switch statement.
+ */
+ public void checkSwitchStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The same local name may not be assigned in more than one case expression in a switch statement.
+ */
+ public void checkSwitchStatementCaseAssignments() {
+
+ }
+
+
+ public void checkSwitchStatementEnclosedStatements() {
+
+ }
+
+ public void checkSwitchStatementExpression() {
+
+ }
+
+ /*
+ * An switch statement is assured if it has an @assured annotation.
+ */
+ public void checkSwitchStatementIsAssuredDerivation() {
+
+ }
+
+ /*
+ * An switch statement is determined if it has an @determined annotation.
+ */
+ public void checkSwitchStatementIsDeterminedDerivation() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * In addition to an @isolated annotation, a switch statement may have @assured and @determined
+ * annotations. They may not have arguments.
+ */
+ public boolean annotationAllowed(Annotation annotation) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/WhileStatement.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/WhileStatement.java new file mode 100644 index 00000000000..f89aec0bc56 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/statements/WhileStatement.java @@ -0,0 +1,48 @@ +package org.eclipse.papyrus.alf.syntax.statements;
+
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class WhileStatement extends Statement {
+
+ // Synthesized Properties
+ public Block body ;
+ public Expression condition ;
+
+ // Constraints
+
+ /*
+ * If a name is assigned before the block, but the assigned source for the name after the block is different
+ * than before the block, then the assigned source of the name after the while statement is the while
+ * statement. Otherwise it is the same as before the block. If a name is unassigned before the block of a
+ * while statement, then it is unassigned after the while statement, even if it is assigned after the block.
+ */
+ public void checkWhileStatementAssignmentsAfter() {
+
+ }
+
+ /*
+ * The assignments before the condition expression of a while statement are the same as the assignments
+ * before the while statement. The assignments before the block of the while statement are the same as the
+ * assignments after the condition expression.
+ */
+ public void checkWhileStatementAssignmentsBefore() {
+
+ }
+
+ /*
+ * The condition expression of a while statement must have type Boolean and a multiplicity upper bound of
+ * 1.
+ */
+ public void checkWhileStatementCondition() {
+
+ }
+
+ /*
+ * The enclosing statement for all statements in the body of a while statement are the while statement.
+ */
+ public void checkWhileStatementEnclosedStatements() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ActiveClassDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ActiveClassDefinition.java new file mode 100644 index 00000000000..fd4b695e40d --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ActiveClassDefinition.java @@ -0,0 +1,18 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class ActiveClassDefinition extends ClassDefinition {
+
+ // Synthesized Properties
+ public ActivityDefinition classifierBehavior ;
+
+ // Helper Operations
+
+ /*
+ * Returns true if the given unit definition matches this active class definition considered as a class
+ * definition and the subunit is for an active class definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ActivityDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ActivityDefinition.java new file mode 100644 index 00000000000..e40522bc2e0 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ActivityDefinition.java @@ -0,0 +1,47 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.statements.Block;
+
+public class ActivityDefinition extends ClassifierDefinition {
+
+ // Synthesized Properties
+ public Block body ;
+
+ // Constraints
+
+ /*
+ * If an activity definition is primitive, then it must have a body that is empty.
+ */
+ public void checkActivityDefinitionPrimitive() {
+
+ }
+
+ /*
+ * An activity definition may not have a specialization list.
+ */
+ public void checkActivityDefinitionSpecialization() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed for classifiers in general, an activity definition allows @primitive
+ * annotations and any stereotype whose metaclass is consistent with Activity.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return super.annotationAllowed(annotation) && false ;
+ }
+
+ /*
+ * Returns true if the given unit definition matches this activity definition considered as a classifier
+ * definition and the subunit is for an activity definition. In addition, the subunit definition must have
+ * formal parameters that match each of the formal parameters of the stub definition, in order. Two formal
+ * parameters match if they have the same direction, name, multiplicity bounds, ordering, uniqueness and
+ * type reference.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/AssociationDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/AssociationDefinition.java new file mode 100644 index 00000000000..0acab8500c0 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/AssociationDefinition.java @@ -0,0 +1,41 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class AssociationDefinition extends ClassifierDefinition {
+
+ // Constraints
+
+ /*
+ * The specialization referents of an association definition must all be associations.
+ */
+ public void checkAssociationDefinitionSpecializationReferent() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed for classifiers in general, an association definition allows an
+ * annotation for any stereotype whose metaclass is consistent with Association.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return super.annotationAllowed(annotation) && false ;
+ }
+
+ /*
+ * Return true if the given member is either an AssociationDefinition or an imported member whose
+ * referent is an AssociationDefinition or an Association.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true if the given unit definition matches this association definition considered as a classifier
+ * definition and the subunit is for an association definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassDefinition.java new file mode 100644 index 00000000000..ad04db319fe --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassDefinition.java @@ -0,0 +1,42 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class ClassDefinition extends ClassifierDefinition {
+
+ // Constraints
+
+ /*
+ * The specialization referents of a class definition must all be classes. A class definition may not have any
+ * referents that are active classes unless this is an active class definition.
+ */
+ public void checkClassDefinitionSpecializationReferent() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed for classifiers in general, a class definition allows an annotation
+ * for any stereotype whose metaclass is consistent with Class.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return super.annotationAllowed(annotation) && false ;
+ }
+
+ /*
+ * Return true if the given member is either a ClassDefinition or an imported member whose referent is a
+ * ClassDefinition or a Class.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true if the given unit definition matches this class definition considered as a classifier definition
+ * and the subunit is for a class definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassifierDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassifierDefinition.java new file mode 100644 index 00000000000..5e15a172615 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassifierDefinition.java @@ -0,0 +1,60 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class ClassifierDefinition extends NamespaceDefinition {
+
+ // Synthesized Properties
+ public boolean isAbstract = false ;
+ public QualifiedName specialization ;
+
+ // Derived Properties
+ public List<ElementReference> specializationReferent ;
+
+ // Constraints
+
+ /*
+ * The members of a classifier definition include non-private members inherited from the classifiers it
+ * specializes. The visibility of inherited members is as specified in the UML Superstructure, Subclause
+ * 7.3.8.
+ */
+ public void checkClassifierDefinitionInheritedMembers() {
+
+ }
+
+ /*
+ * Each name listed in the specialization list for a classifier definition must have a single classifier referent.
+ * None of these referents may be templates.
+ */
+ public void checkClassifierDefinitionSpecialization() {
+
+ }
+
+ /*
+ * The specialization referents of a classifier definition are the classifiers denoted by the names in the
+ * specialization list for the classifier definition.
+ */
+ public void checkClassifierDefinitionSpecializationReferentDerivation() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * The namespace definition associated with the given unit definition must be a classifier definition. The
+ * subunit classifier definition may be abstract if and only if the subunit classifier definition is abstract. The
+ * subunit classifier definition must have the same specialization referents as the stub classifier definition.
+ * (Note that it is the referents that must match, not the exact names or the ordering of those names in the
+ * specialization list.) The subunit classifier definition must also have a matching classifier template
+ * parameter for each classifier template parameter of the stub classifier definition. Two template
+ * parameters match if they have same names and the same specialization referents.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassifierTemplateParameter.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassifierTemplateParameter.java new file mode 100644 index 00000000000..b1f6e954d77 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ClassifierTemplateParameter.java @@ -0,0 +1,29 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class ClassifierTemplateParameter extends ClassifierDefinition {
+
+ // Helper Operations
+
+ /*
+ * Annotations are not allowed on classifier template parameters.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is a classifier template parameter.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns false. (Classifier template parameters cannot be stubs.)
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/DataTypeDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/DataTypeDefinition.java new file mode 100644 index 00000000000..019b67f9b68 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/DataTypeDefinition.java @@ -0,0 +1,48 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class DataTypeDefinition extends ClassifierDefinition {
+
+ // Constraints
+
+ /*
+ * If a data type is primitive, then it may not have any owned members.
+ */
+ public void checkDataTypeDefinitionPrimitive() {
+
+ }
+
+ /*
+ * The specialization referents of a data type definition must all be data types.
+ */
+ public void checkDataTypeDefinitionSpecializationReferent() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed for classifiers in general, a data type definition allows @primitive
+ * annotations plus any stereotype whose metaclass is consistent with DataType.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return super.annotationAllowed(annotation) && false ;
+ }
+
+ /*
+ * Return true if the given member is either a DataTypeDefinition or an imported member whose referent
+ * is a DataTypeDefinition or a DataType.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true if the given unit definition matches this data type definition considered as a classifier
+ * definition and the subunit is for a data type definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ElementImportReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ElementImportReference.java new file mode 100644 index 00000000000..f9070b941d7 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ElementImportReference.java @@ -0,0 +1,8 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class ElementImportReference extends ImportReference {
+
+ // Synthesized Properties
+ public String alias ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/EnumerationDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/EnumerationDefinition.java new file mode 100644 index 00000000000..fbb9a509ac4 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/EnumerationDefinition.java @@ -0,0 +1,42 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class EnumerationDefinition extends ClassifierDefinition {
+
+ // Constraints
+
+ /*
+ * The specialization referents of a class definition must all be classes. A class definition may not have any
+ * referents that are active classes unless this is an active class definition.
+ */
+ public void checkClassDefinitionSpecializationReferent() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed for classifiers in general, an enumeration definition allows an
+ * annotation for any stereotype whose metaclass is consistent with Enumeration.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return super.annotationAllowed(annotation) && false ;
+ }
+
+ /*
+ * Return true if the given member is either an EnumerationDefinition or an imported member whose
+ * referent is an EnumerationDefinition or an Enumeration.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true if the given unit definition matches this enumeration definition considered as a classifier
+ * definition and the subunit is for an enumeration definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/EnumerationLiteralName.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/EnumerationLiteralName.java new file mode 100644 index 00000000000..ad08cdc367a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/EnumerationLiteralName.java @@ -0,0 +1,15 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class EnumerationLiteralName {
+
+ // Helper Operations
+
+ /*
+ * Returns false. (Enumeration literal name cannot have annotations.)
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/FormalParameter.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/FormalParameter.java new file mode 100644 index 00000000000..c982a0d9e8e --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/FormalParameter.java @@ -0,0 +1,24 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class FormalParameter extends TypedElementDefinition {
+
+ // Synthesized Properties
+ public String direction ;
+
+ // Helper Operations
+
+ /*
+ * Returns true if the annotation is for a stereotype that has a metaclass consistent with Parameter.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is a FormalParameter.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ImportReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ImportReference.java new file mode 100644 index 00000000000..c1a0b5284ed --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ImportReference.java @@ -0,0 +1,33 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class ImportReference extends SyntaxElement {
+
+ public QualifiedName referentName ;
+ public UnitDefinition unit ;
+ public String visibility ;
+
+ //Derived Properties
+ public ElementReference referent ;
+
+ // Constraints
+
+ /*
+ * The referent name of an import reference must resolve to a single element with public or empty
+ * visibility.
+ */
+ public void checkImportReferenceReferent() {
+
+ }
+
+ /*
+ * The referent of an import reference is the element denoted by the referent name.
+ */
+ public void checkImportReferenceReferentDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ImportedMember.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ImportedMember.java new file mode 100644 index 00000000000..7bc24fbcce5 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ImportedMember.java @@ -0,0 +1,49 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+
+public class ImportedMember extends Member {
+
+ // Synthesized Properties
+ public ElementReference referent ;
+
+ // Constraints
+
+ /*
+ * An imported element is a feature if its referent is a feature.
+ */
+ public void checkImportedElementFeatureDerivation() {
+
+ }
+
+ /*
+ * An imported element is not a stub.
+ */
+ public void checkImportedElementNotStub() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * Returns false. (Imported members do not have annotations.)
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * If the given member is not an imported member, then return the result of checking whether the given
+ * member is distinguishable from this member. Else, if the element of the referent for this member is an
+ * Alf member, then return the result of checking whether that element is distinguishable from the given
+ * member. Else, if the element of the referent for the given member is an Alf member, then return the
+ * result of checking whether that element is distinguishable from this member. Else, the referents for both
+ * this and the given member are UML elements, so return the result of checking their distinguishability
+ * according to the rules of the UML superstructure.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/Member.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/Member.java new file mode 100644 index 00000000000..9fb7a18d8b1 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/Member.java @@ -0,0 +1,121 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.DocumentedElement;
+
+public class Member extends DocumentedElement {
+
+ // Synthesized Properties
+ public List<StereotypeAnnotation> annotation ;
+ public boolean isStub = false ;
+ public String name ;
+ public NamespaceDefinition namespace ;
+ public String visibility ;
+
+ // Derived Properties
+ public boolean isExternal ;
+ public boolean isFeature = false ;
+ public boolean isPrimitive ;
+ public UnitDefinition subunit ;
+
+ // Constraints
+
+ /*
+ * All stereotype annotations for a member must be allowed, as determined using the stereotypeAllowed
+ * operation.
+ */
+ public void checkMemberAnnotations() {
+
+ }
+
+ /*
+ * If a member is external then it must be a stub.
+ */
+ public void checkMemberExternal() {
+
+ }
+
+ /*
+ * A member is external if it has an @external derivation.
+ */
+ public void checkMemberIsExternalDerivation() {
+
+ }
+
+ /*
+ * A member is primitive if it has a @primitive annotation.
+ */
+ public void checkMemberIsPrimitiveDerivation() {
+
+ }
+
+ /*
+ * If a member is primitive, then it may not be a stub and it may not have any owned members that are
+ * template parameters.
+ */
+ public void checkMemberPrimitive() {
+
+ }
+
+ /*
+ * If a member is a stub and is not external, then there must be a single subunit with the same qualified
+ * name as the stub that matches the stub, as determined by the matchForStub operation.
+ */
+ public void checkMemberStub() {
+
+ }
+
+ /*
+ * If a member is a stub, then the it must not have any stereotype annotations that are the same as its
+ * subunit. Two stereotype annotations are the same if they are for the same stereotype.
+ */
+ public void checkMemberStubStereotypes() {
+
+ }
+
+ /*
+ * If the member is a stub and is not external, then its corresponding subunit is a unit definition with the
+ * same fully qualified name as the stub.
+ */
+ public void checkMemberSubunitDerivation() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * Returns true of the given stereotype annotation is allowed for this kind of element.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Returns true if this member is distinguishable from the given member. Two members are distinguishable
+ * if their names are different or the they are of different kinds (as determined by the isSameKindAs
+ * operation). However, in any case that the UML Superstructure considers two names to be
+ * distinguishable if they are different, an Alf implementation may instead impose the stronger requirement
+ * that the names not be conflicting.
+ */
+ public boolean isDistinguishableFrom(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true if this member is of the same kind as the given member.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true of the given unit definition is a legal match for this member as a stub. By default, always
+ * returns false.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/NamespaceDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/NamespaceDefinition.java new file mode 100644 index 00000000000..fe0d57172b9 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/NamespaceDefinition.java @@ -0,0 +1,46 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+public class NamespaceDefinition extends Member {
+
+ // Synthesized Properties
+ public List<Member> ownedMember ;
+ public UnitDefinition unit ;
+
+ // Derived Properties
+ public List<Member> member ;
+
+ // Constraints
+
+ /*
+ * The members of a namespace definition include references to all owned members. Also, if the
+ * namespace definition has a unit with imports, then the members include imported members with
+ * referents to all imported elements. The imported elements and their visibility are determined as given in
+ * the UML Superstructure. The name of an imported member is the name of the imported element or its
+ * alias, if one has been given for it. Elements that would be indistinguishable from each other or from an
+ * owned member (as determined by the Member::isDistinguishableFrom operation) are not imported.
+ */
+ public void checkNamespaceDefinitionMemberDerivation() {
+
+ }
+
+ /*
+ * The members of a namespace must be distinguishable as determined by the
+ * Member::isDistinguishableFrom operation.
+ */
+ public void checkNamespaceDefinitionMemberDistinguishaibility() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * Returns true if the annotation is @external.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/OperationDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/OperationDefinition.java new file mode 100644 index 00000000000..54410d82719 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/OperationDefinition.java @@ -0,0 +1,133 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.statements.Block;
+import org.eclipse.papyrus.alf.syntax.statements.QualifiedNameList;
+
+public class OperationDefinition extends NamespaceDefinition{
+
+ // Synthesized Properties
+ public Block body ;
+ public boolean isAbstract = false ;
+ public QualifiedNameList redefinition ;
+
+ // Derived Properties
+ public boolean isConstructor ;
+ public boolean isDestructor ;
+ public List<ElementReference> redefinedOperations ;
+
+ // Constraints
+
+ /*
+ * If an operation definition is a constructor, any redefined operation for it must also be a constructor. The
+ * body of a constructor may contain an alternative constructor invocation for another constructor in the
+ * same class or super constructor invocations for constructors in immediate superclasses.
+ */
+ public void checkOperationDefinitionConstructor() {
+
+ }
+
+ /*
+ * An operation definition cannot be both a constructor and a destructor.
+ */
+ public void checkOperationDefinitionConstructorDestructor() {
+
+ }
+
+ /*
+ * If an operation definition is a destructor, any redefined operation for it must also be a destructor.
+ */
+ public void checkOperationDefinitionDestructor() {
+
+ }
+
+ /*
+ * An operation definition is a constructor if it has a @Create annotation.
+ */
+ public void checkOperationDefinitionIsConstructorDefinition() {
+
+ }
+
+ /*
+ * An operation definition is a destructor if it has a @Destroy annotation.
+ */
+ public void checkOperationDefinitionIsDestructorDefinition() {
+
+ }
+
+ /*
+ * An operation definition is a feature.
+ */
+ public void checkOperationDefinitionIsFeatureDerivation() {
+
+ }
+
+ /*
+ * The namespace for an operation definition must be a class definition. If the operation definition is
+ * abstract, then the class definition must be abstract.
+ */
+ public void checkOperationDefinitionNamespace() {
+
+ }
+
+ /*
+ * The redefined operations of an operation definition must have formal parameters that match each of the
+ * formal parameters of this operation definition, in order. Two formal parameters match if they have the
+ * same direction, name, multiplicity bounds, ordering, uniqueness and type reference.
+ */
+ public void checkOperationDefinitionRedefinedOperations() {
+
+ }
+
+ /*
+ * If an operation definition has a redefinition list, its redefined operations are the referent operations of the
+ * names in the redefinition list for the operation definition. Otherwise, the redefined operations are any
+ * operations that would otherwise be indistinguishable from the operation being defined in this operation
+ * definition.
+ */
+ public void checkOperationDefinitionRedefinedOperationsDerivation() {
+
+ }
+
+ /*
+ * Each name in the redefinition list of an operation definition must have a signal referent that is an
+ * operation. This operation must be a non-private operation that is a member of a specialization referent of
+ * the class definition of the operation definition.
+ */
+ public void checkOperationDefinitionRedefinition() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * Returns true if the annotation is for a stereotype that has a metaclass consistent with Operation.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is either an OperationDefinition or an imported member whose referent
+ * is an OperationDefinition or an Operation, and the formal parameters of this operation definition match,
+ * in order, the parameters of the other operation definition or operation. In this context, matching means
+ * the same name and type (per UML Superstructure, Subclause 7.3.5).
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * The namespace definition associated with the given unit definition must be an activity definition with no
+ * template parameters. In addition, the subunit definition must have formal parameters that match each of
+ * the formal parameters of the stub definition, in order. Two formal parameters match if they have the
+ * same direction, name, multiplicity bounds, ordering, uniqueness and type reference.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PackageDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PackageDefinition.java new file mode 100644 index 00000000000..8ad47c8eb0a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PackageDefinition.java @@ -0,0 +1,49 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+import org.eclipse.uml2.uml.Profile;
+
+public class PackageDefinition extends NamespaceDefinition {
+
+ // Derived Properties
+ public List<Profile> appliedProfile ;
+
+ // Constraints
+
+ /*
+ * The applied profiles of a package definition are the profiles listed in any @apply annotations on the
+ * package.
+ */
+ public void checkPackageDefinitionAppliedProfileDerivation() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed on any namespace definition, a package definition allows @apply
+ * annotations plus any stereotype whose metaclass is consistent with Package.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is either a PackageDefinition or an imported member whose referent is
+ * a PackageDefinition or a Package.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true of the namespace definition associated with the given unit definition is a package
+ * definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PackageImportReference.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PackageImportReference.java new file mode 100644 index 00000000000..f92cdfc0e63 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PackageImportReference.java @@ -0,0 +1,14 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class PackageImportReference extends ImportReference {
+
+ // Constraints
+
+ /*
+ * The referent of a package import must be a package.
+ */
+ public void checkPackageImportReferenceReferent() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PropertyDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PropertyDefinition.java new file mode 100644 index 00000000000..375106a0286 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/PropertyDefinition.java @@ -0,0 +1,67 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.expressions.Expression;
+
+public class PropertyDefinition extends TypedElementDefinition {
+
+ // Synthesized Properties
+ public Expression initializer ;
+ public boolean isComposite = false ;
+
+ // Derived Properties
+ public boolean isBitStringConversion ;
+ public boolean isCollectionConversion ;
+
+ // Constraints
+
+ /*
+ * If a property definition has an initializer, then the initializer expression must be assignable to the
+ * property definition.
+ */
+ public void checkPropertyDefinitionInitializer() {
+
+ }
+
+ /*
+ * A property definition requires BitString conversion if its type is BitString and the type of its initializer is
+ * Integer or a collection class whose argument type is Integer.
+ */
+ public void checkPropertyDefinitionIsBitStringConversion() {
+
+ }
+
+ /*
+ * A property definition requires collection conversion if its initializer has a collection class as its type and
+ * the property definition does not.
+ */
+ public void checkPropertyDefinitionIsCollectionConversionDerivation() {
+
+ }
+
+ /*
+ * A property definition is a feature.
+ */
+ public void checkPropertyDefinitionIsFeatureDerivation() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * Returns true if the annotation is for a stereotype that has a metaclass consistent with Property.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is either a PropertyDefinition or an imported member whose referent is
+ * a PropertyDefinition or a Property.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ReceptionDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ReceptionDefinition.java new file mode 100644 index 00000000000..3b08f836e89 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/ReceptionDefinition.java @@ -0,0 +1,56 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class ReceptionDefinition extends Member {
+
+ // Synthesized Properties
+ public QualifiedName signalName ;
+
+ // Derived Properties
+ public ElementReference signal ;
+
+ // Constraints
+
+ /*
+ * A reception definition is a feature.
+ */
+ public void checkReceptionDefinitionIsFeatureDerivation() {
+
+ }
+
+ /*
+ * The signal for a reception definition is the signal referent of the signal name for the reception definition.
+ */
+ public void checkReceptionDefinitionSignalDerivation() {
+
+ }
+
+ /*
+ * The signal name for a reception definition must have a single referent that is a signal. This referent must
+ * not e a template.
+ */
+ public void checkReceptionDefinitionSignalName() {
+
+ }
+
+
+ // Helper Operations
+
+ /*
+ * Returns true if the annotation is for a stereotype that has a metaclass consistent with Reception.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is either a ReceptionDefinition, a SignalReceptionDefinition or an
+ * imported member whose referent is a ReceptionDefinition, a SignalReceptionDefinition or a Reception.
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/SignalDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/SignalDefinition.java new file mode 100644 index 00000000000..ce708a4137e --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/SignalDefinition.java @@ -0,0 +1,41 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class SignalDefinition extends ClassifierDefinition {
+
+ // Constraints
+
+ /*
+ * The specialization referents of a signal definition must all be signals.
+ */
+ public void checkSignalDefinitionSpecializationReferent() {
+
+ }
+
+ // Helper Operations
+
+ /*
+ * In addition to the annotations allowed for classifiers in general, a signal definition allows an annotation
+ * for any stereotype whose metaclass is consistent with Signal.
+ */
+ public boolean annotationAllowed(StereotypeAnnotation annotation) {
+ return false ;
+ }
+
+ /*
+ * Return true if the given member is either a SignalDefinition or an imported member whose referent is a
+ * SignalDefinition or a Reception (where signal reception definitions are considered to be kinds of signal
+ * definitions).
+ */
+ public boolean isSameKindAs(Member member) {
+ return false ;
+ }
+
+ /*
+ * Returns true if the given unit definition matches this signal definition considered as a classifier
+ * definition and the subunit is for a signal definition.
+ */
+ public boolean matchForStub(UnitDefinition unit) {
+ return false ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/SignalReceptionDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/SignalReceptionDefinition.java new file mode 100644 index 00000000000..1a1a8751111 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/SignalReceptionDefinition.java @@ -0,0 +1,14 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+public class SignalReceptionDefinition extends SignalDefinition {
+
+ // Constraints
+
+ /*
+ * A signal reception definition is a feature.
+ */
+ public void checkSignalReceptionDefinitionIsFeatureDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/StereotypeAnnotation.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/StereotypeAnnotation.java new file mode 100644 index 00000000000..5150764af4d --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/StereotypeAnnotation.java @@ -0,0 +1,80 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+import org.eclipse.papyrus.alf.syntax.statements.QualifiedNameList;
+import org.eclipse.uml2.uml.Stereotype;
+
+public class StereotypeAnnotation extends SyntaxElement {
+
+ // Synthesized Properties
+ public QualifiedNameList names ;
+ public QualifiedName stereotypeName ;
+ public TaggedValueList taggedValues ;
+
+ // Derived Properties
+ public Stereotype stereotype ;
+
+ // Constraints
+
+ /*
+ * If the stereotype name of a stereotype annotation is "apply", then it must have a name list and all of the
+ * names in the list must resolve to profiles.
+ */
+ public void checkStereotypeAnnotationApply() {
+
+ }
+
+ /*
+ * If the stereotype name of a stereotype annotation is "external", then it may optionally have a single
+ * tagged value with the name "file" and no operator.
+ */
+ public void checkStereotypeAnnotationExternal() {
+
+ }
+
+ /*
+ * If a stereotype annotation has a stereotype and a list of names, then all the names in the list must resolve
+ * to visible model elements and the stereotype must have a single attribute with a (metaclass) type and
+ * multiplicity that are consistent with the types and number of the elements denoted by the given names.
+ */
+ public void checkStereotypeAnnotationNames() {
+
+ }
+
+ /*
+ * If the stereotype name of a stereotype annotation is "primitive", then it may not have tagged values or
+ * names.
+ */
+ public void checkStereotypeAnnotationPrimitive() {
+
+ }
+
+ /*
+ * Unless the stereotype name is "apply", "primitive" or "external" then the stereotype for a stereotype
+ * annotation is the stereotype denoted by the stereotype name.
+ */
+ public void checkStereotypeAnnotationStereotypeDerivation() {
+
+ }
+
+ /*
+ * The stereotype name of a stereotype annotation must either be one of "apply", "primitive" or "external",
+ * or it must denote a single stereotype from a profile applied to an enclosing package. The stereotype
+ * name does not need to be qualified if there is only one applied profile with a stereotype of that name or
+ * if the there is a standard UML profile with the name.
+ */
+ public void checkStereotypeAnnotationStereotypeName() {
+
+ }
+
+ /*
+ * If a stereotype annotation has a stereotype and tagged values, then the each tagged value must have the
+ * name of an attribute of the stereotype and a value that is legally interpretable for the type of that
+ * attribute.
+ */
+ public void checkStereotypeAnnotationTaggedValues() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TaggedValue.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TaggedValue.java new file mode 100644 index 00000000000..d47a941f2ef --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TaggedValue.java @@ -0,0 +1,12 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class TaggedValue extends SyntaxElement {
+
+ // Synthesized Properties
+ public String name ;
+ public String operator ;
+ public String value ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TaggedValueList.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TaggedValueList.java new file mode 100644 index 00000000000..de246ae84bc --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TaggedValueList.java @@ -0,0 +1,12 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.SyntaxElement;
+
+public class TaggedValueList extends SyntaxElement {
+
+ // Synthesized Properties
+ public List<TaggedValue> taggedValue ;
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TypedElementDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TypedElementDefinition.java new file mode 100644 index 00000000000..6a85d0eaa75 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/TypedElementDefinition.java @@ -0,0 +1,54 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+
+public class TypedElementDefinition extends Member {
+
+ // Synthesized Properties
+ public boolean isNonunique = false ;
+ public boolean isOrdered = false ;
+ public String lowerBound ;
+ public QualifiedName typeName ;
+ public String upperBound = "1" ;
+
+ // Derived Properties
+ public int lower ;
+ public ElementReference type ;
+ public int upper ;
+
+ // Constraints
+
+ /*
+ * If the lower bound string image of a typed element definition is not empty, then the integer lower bound
+ * is the integer value of the lower bound string. Otherwise the lower bound is equal to the upper bound,
+ * unless the upper bound is unbounded, in which case the lower bound is 0.
+ */
+ public void checkTypedElementDefinitionLowerDerivation() {
+
+ }
+
+ /*
+ * The type of a typed element definition is the single classifier referent of the type name.
+ */
+ public void checkTypedElementDefinitionTypeDerivation() {
+
+ }
+
+ /*
+ * The type name of a typed element definition must have a single classifier referent. This referent may not
+ * be a template.
+ */
+ public void checkTypedElementDefinitionTypeName() {
+
+ }
+
+ /*
+ * The unlimited natural upper bound value is the unlimited natural value of the uper bound string (with
+ * "*" representing the unbounded value).
+ */
+ public void checkTypedElementDefinitionUpperDerivation() {
+
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/UnitDefinition.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/UnitDefinition.java new file mode 100644 index 00000000000..0f2be6f59d2 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/syntax/units/UnitDefinition.java @@ -0,0 +1,66 @@ +package org.eclipse.papyrus.alf.syntax.units;
+
+import java.util.List;
+
+import org.eclipse.papyrus.alf.syntax.common.DocumentedElement;
+import org.eclipse.papyrus.alf.syntax.common.ElementReference;
+import org.eclipse.papyrus.alf.syntax.expressions.QualifiedName;
+import org.eclipse.uml2.uml.Profile;
+
+public class UnitDefinition extends DocumentedElement {
+
+ // Synthesized properties
+ public List<ImportReference> _import ;
+ public NamespaceDefinition definition ;
+ public QualifiedName namespaceName ;
+
+ // Derived Properties
+ public List<Profile> appliedProfile ;
+ public boolean isModelLibrary ;
+ public ElementReference namespace ;
+
+ // Constraints
+
+ /*
+ * The profiles applied to a unit definition include any profiles applied to the containing namespace of the
+ * unit definition. If the unit definition is for a package, then the applied profiles for the unit definition also
+ * include the applied profiles for its associated package definition.
+ */
+ public void checkUnitDefinitionAppliedProfileDerivation() {
+
+ }
+
+ /*
+ * Unless the unit definition is a model library, it has private package import references for all the subpackages
+ * of the Alf::Library package.
+ */
+ public void checkUnitDefinitionImplicitImports() {
+
+ }
+
+ /*
+ * A unit definition is for a model library if its associated namespace definition has a stereotype annotation
+ * for the UML standard stereotype ModelLibrary.
+ */
+ public void checkUnitDefinitionIsModelLibraryDerivation() {
+
+ }
+
+ /*
+ * The declared namespace name for a unit definition, if any, must resolve to a UML namespace of an Alf
+ * unit definition. If it is an Alf unit definition, then it must have a stub for this unit definition.
+ */
+ public void checkUnitDefinitionNamespace() {
+
+ }
+
+ /*
+ * If a unit definition has a declared namespace name, then the containing namespace for the unit is the
+ * referent for that name.
+ */
+ public void checkUnitDefinitionNamespaceDerivation() {
+
+ }
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java new file mode 100644 index 00000000000..d87f9692a93 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/AlfJavaValidator.java @@ -0,0 +1,1441 @@ +/***************************************************************************** + * Copyright (c) 2011 CEA LIST. + * + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * CEA LIST - Initial API and implementation + * + *****************************************************************************/ +package org.eclipse.papyrus.alf.validation; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.operations.OperationHistoryFactory; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.gmf.runtime.common.core.command.CommandResult; +import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.papyrus.alf.alf.AcceptBlock; +import org.eclipse.papyrus.alf.alf.AcceptStatement; +import org.eclipse.papyrus.alf.alf.AlfPackage; +import org.eclipse.papyrus.alf.alf.AssignmentOperator; +import org.eclipse.papyrus.alf.alf.ClassificationClause; +import org.eclipse.papyrus.alf.alf.ClassificationFromClause; +import org.eclipse.papyrus.alf.alf.ClassificationToClause; +import org.eclipse.papyrus.alf.alf.ClassifyStatement; +import org.eclipse.papyrus.alf.alf.ConcurrentClauses; +import org.eclipse.papyrus.alf.alf.DoStatement; +import org.eclipse.papyrus.alf.alf.DocumentedStatement; +import org.eclipse.papyrus.alf.alf.ForStatement; +import org.eclipse.papyrus.alf.alf.IfStatement; +import org.eclipse.papyrus.alf.alf.InstanceCreationInvocationStatement; +import org.eclipse.papyrus.alf.alf.InvocationOrAssignementOrDeclarationStatement; +import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement; +import org.eclipse.papyrus.alf.alf.LoopVariableDefinition; +import org.eclipse.papyrus.alf.alf.NameExpression; +import org.eclipse.papyrus.alf.alf.NonEmptyStatementSequence; +import org.eclipse.papyrus.alf.alf.NonFinalClause; +import org.eclipse.papyrus.alf.alf.PropertyCallExpression; +import org.eclipse.papyrus.alf.alf.QualifiedNameList; +import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding; +import org.eclipse.papyrus.alf.alf.ReturnStatement; +import org.eclipse.papyrus.alf.alf.StatementSequence; +import org.eclipse.papyrus.alf.alf.SuffixExpression; +import org.eclipse.papyrus.alf.alf.SuperInvocationStatement; +import org.eclipse.papyrus.alf.alf.ThisInvocationStatement; +import org.eclipse.papyrus.alf.alf.TupleElement; +import org.eclipse.papyrus.alf.alf.UnqualifiedName; +import org.eclipse.papyrus.alf.alf.VariableDeclarationCompletion; +import org.eclipse.papyrus.alf.alf.WhileStatement; +import org.eclipse.papyrus.alf.scoping.AlfPartialScope; +import org.eclipse.papyrus.alf.scoping.AlfScopeProvider; +import org.eclipse.papyrus.alf.validation.typing.AssignmentPolicy; +import org.eclipse.papyrus.alf.validation.typing.ErrorTypeFacade; +import org.eclipse.papyrus.alf.validation.typing.MultiplicityFacade; +import org.eclipse.papyrus.alf.validation.typing.MultiplicityFacadeFactory; +import org.eclipse.papyrus.alf.validation.typing.SignatureFacade; +import org.eclipse.papyrus.alf.validation.typing.TypeExpression; +import org.eclipse.papyrus.alf.validation.typing.TypeExpressionFactory; +import org.eclipse.papyrus.alf.validation.typing.TypeFacade; +import org.eclipse.papyrus.alf.validation.typing.TypeFacadeFactory; +import org.eclipse.papyrus.alf.validation.typing.TypeUtils; +import org.eclipse.papyrus.alf.validation.typing.VoidFacade; +import org.eclipse.papyrus.core.utils.EditorUtils; +import org.eclipse.papyrus.extensionpoints.uml2.library.RegisteredLibrary; +import org.eclipse.papyrus.extensionpoints.uml2.utils.Util; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.uml2.uml.Class; +import org.eclipse.uml2.uml.Classifier; +import org.eclipse.uml2.uml.Comment; +import org.eclipse.uml2.uml.Element; +import org.eclipse.uml2.uml.Model; +import org.eclipse.uml2.uml.Namespace; +import org.eclipse.uml2.uml.Operation; +import org.eclipse.uml2.uml.Package; +import org.eclipse.uml2.uml.PackageImport; +import org.eclipse.uml2.uml.Parameter; +import org.eclipse.uml2.uml.ParameterDirectionKind; +import org.eclipse.uml2.uml.UMLFactory; +import org.eclipse.uml2.uml.resource.UMLResource; +import org.eclipse.uml2.uml.resource.UMLResource.Factory; +import org.eclipse.uml2.uml.util.UMLUtil.UML2EcoreConverter; +import org.eclipse.xtext.validation.Check; +import org.eclipse.xtext.validation.EValidatorRegistrar; + + +public class AlfJavaValidator extends AbstractAlfJavaValidator { + + private static Element contextElement ; + private static Classifier contextClassifier ; + private static Namespace model ; + + private static Package alfStandardLibrary ; // TODO: include the library as part of the plug-in + public static PredefinedBehaviorsAndTypesUtils predefinedBehaviorsAndTypes ; + + public static Package getAlfStandardLibrary() { + return alfStandardLibrary; + } + + public static boolean validate() { + return true ; + } + + public static Namespace getModel() { + return model; + } + + public static void setModel(Namespace model) { + AlfJavaValidator.model = model; + } + + public static void setContextElement(Element _contextElement) { + contextElement = _contextElement ; + } + + public static Element getContextElement() { + return contextElement ; + } + + public static Classifier getContextClassifier() { + return contextClassifier ; + } + + public static void setContextClassifier(Classifier contextClassifier) { + AlfJavaValidator.contextClassifier = contextClassifier ; + alfStandardLibrary = null ; + //if (alfStandardLibrary == null) { + for (PackageImport pImport : contextClassifier.getModel().getPackageImports()) { + Package p = pImport.getImportedPackage() ; + if (p.getQualifiedName().equals("Alf")) { + //alfStandardLibrary = (Package)p.getOwnedMembers().get(0) ; + alfStandardLibrary = (Package)p ; + } + } + //} + if (alfStandardLibrary != null) { + predefinedBehaviorsAndTypes = new PredefinedBehaviorsAndTypesUtils() ; + predefinedBehaviorsAndTypes.init(alfStandardLibrary) ; + } + else { + + String question = "The context model " + + contextClassifier.getModel().getName() + + " does not import the standard Alf library. This import is required for static validation of Alf expressions and statements. \n\n Do you want to generate this import?" ; + boolean doGenerateImport = MessageDialog.openQuestion( + new Shell(), + "Alf editor", + question); + if (doGenerateImport) { + RegisteredLibrary[] libraries = RegisteredLibrary.getRegisteredLibraries() ; + RegisteredLibrary alfLibrary = null ; + for (RegisteredLibrary l : libraries) { + if (l.getName().equals("AlfLibrary")) + alfLibrary = l ; + } + if (alfLibrary != null) { + // Creates and executes the update command + UpdateImportCommand updateCommand = new UpdateImportCommand(contextClassifier.getModel(), alfLibrary); + try { + OperationHistoryFactory.getOperationHistory().execute(updateCommand, new NullProgressMonitor(), null); + setContextClassifier(contextClassifier) ; + } catch (ExecutionException e) { + org.eclipse.papyrus.properties.runtime.Activator.log.error(e); + } + } + else { + MessageDialog.openError( + new Shell(), + "Alf editor", + "Could not find standard Alf library") ; + } + } + } + } + + /** + * @author CEA LIST + * + * A command for updating the context UML model + */ + protected static class UpdateImportCommand extends AbstractTransactionalCommand { + + private Model model; + private RegisteredLibrary library ; + + /* + * (non-Javadoc) + * + * @see + * org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor + * , org.eclipse.core.runtime.IAdaptable) + */ + @Override + protected CommandResult doExecuteWithResult(IProgressMonitor arg0, IAdaptable arg1) throws ExecutionException { + URI libraryUri = library.uri; + ResourceSet resourceSet = Util.getResourceSet(contextClassifier) ; + Resource libraryResource = resourceSet.getResource(libraryUri, true) ; + Package libraryObject = (Package)libraryResource.getContents().get(0) ; + model.createPackageImport(libraryObject) ; + return CommandResult.newOKCommandResult(model); + } + + public UpdateImportCommand(Model model, RegisteredLibrary library) { + super(EditorUtils.getTransactionalEditingDomain(), "Model Update", getWorkspaceFiles(model)); + this.model = model ; + this.library = library ; + //this.operation = operation; + } + } + + @Override + public void register(EValidatorRegistrar registrar) { + // alf validator is not registered for a specific language + super.register(registrar) ; + } + + /** + * @param tupleElement + * + * Checks the following rule: + * 1. the expression associated with the tuple must not encapsulate any error + */ + @Check + public void checkTupleElement(TupleElement tupleElement) { + TypeExpression exp = new TypeUtils().getTypeOfExpression(tupleElement.getArgument()) ; + if (exp.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)exp.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + } + + /** + * @param statement LocalNameDeclarationStatement + * + * Checks the following rules: + * 1. the local variable name must be available + * 2. the type must be resolved + * 3. the init expression must be type/multiplicity compatible with the variable type + */ + @Check + public void checkLocalNameDeclarationStatement(LocalNameDeclarationStatement statement) { + // 1. checks that the local variable name is available + if (statement.getVarName() != null) { + AlfPartialScope variablesScope = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(statement) ; + List<EObject> resolved = variablesScope.resolveByName(statement.getVarName()) ; + if (! resolved.isEmpty()) {// name is already used + // needs to determine if the scoping level where it is used is conflicting (i.e., it is in the first scoping level) + if (variablesScope.getScopingLevel(resolved.get(0)) == 0 && resolved.get(0) != statement) { + // There is a name conflict + error("Local name " + statement.getVarName() + " is not available" , AlfPackage.eINSTANCE.getLocalNameDeclarationStatement_VarName()) ; + } + } + } + + // 2. checks that type can be resolved, and that potentially required template bindings are specified + TypeFacade variableType = null ; + if (statement.getType() != null) { + variableType = TypeFacadeFactory.eInstance.createVoidFacade(statement.getType()) ; + if (variableType instanceof ErrorTypeFacade) { // Type could not be resolved + ErrorTypeFacade error = (ErrorTypeFacade)variableType ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + variableType = null ; + } + else if (variableType.isATemplate()){ + if (statement.getType().getBinding() == null) { + String errorMessage = variableType.getLabel() + " is a template. All its parameters shall be bound." ; + error(errorMessage, statement, AlfPackage.eINSTANCE.getLocalNameDeclarationStatement_Type(), INSIGNIFICANT_INDEX) ; + } + } + } + + // 3. checks the init expression + if (statement.getInit() != null) { + TypeExpression typeOfInit = new TypeUtils().getTypeOfSequenceElement(statement.getInit()) ; + // first checks that init expression is valid + if (typeOfInit.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfInit.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + // Type expression is valid + // In the case where type has been validated at step 2., checks if the type of init expression is compatible with variable type + if (variableType != null) { + int lowerBound = statement.isMultiplicityIndicator() ? 0 : 1 ; + int upperBound = statement.isMultiplicityIndicator() ? -1 : 1 ; + boolean isUnique = statement.isMultiplicityIndicator() ? false : true ; + boolean isOrdered = statement.isMultiplicityIndicator() ? true : false ; + TypeExpression expectedType = TypeExpressionFactory.eInstance.createTypeExpression(variableType, lowerBound, upperBound, isUnique, isOrdered) ; + if (expectedType.isCompatibleWithMe(typeOfInit) == 0) { + error("Found an expression of type " + typeOfInit.getLabel() + ". Expecting an expression of type " + expectedType.getLabel(), AlfPackage.eINSTANCE.getLocalNameDeclarationStatement_Init()) ; + } + } + } + } + } + + /** + * @param statement IfStatement + * + * Checks the following rule: + * 1. The condition associated with each clause must be a boolean expression + */ + @Check + public void checkIfStatement(IfStatement statement) { + for (ConcurrentClauses concurrentClause : statement.getSequentialClausses().getConccurentClauses()) { + for (NonFinalClause nonFinalClause : concurrentClause.getNonFinalClause()) { + TypeExpression typeOfCondition = new TypeUtils().getTypeOfExpression(nonFinalClause.getCondition()) ; + if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfCondition.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + if (TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean).isCompatibleWithMe(typeOfCondition) == 0) { + String errorMessage = "Expecting an expression of type Boolean. Found an expression of type " + typeOfCondition.getLabel() ; + error(errorMessage, nonFinalClause, AlfPackage.eINSTANCE.getNonFinalClause_Condition(), INSIGNIFICANT_INDEX) ; + } + } + } + } + } + + /** + * @param statement WhileStatement + * + * Checks the following rule: + * 1. The condition associated with the while must be a boolean expression + */ + @Check + public void checkWhileStatement(WhileStatement statement) { + TypeExpression typeOfCondition = new TypeUtils().getTypeOfExpression(statement.getCondition()) ; + if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfCondition.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + if (TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean).isCompatibleWithMe(typeOfCondition) == 0) { + String errorMessage = "Expecting an expression of type Boolean. Found an expression of type " + typeOfCondition.getLabel() ; + error(errorMessage, AlfPackage.eINSTANCE.getWhileStatement_Condition()) ; + } + } + } + + /** + * @param statement DoStatement + * + * Checks the following rule: + * 1. The condition associated with the DoStatement must be a boolean expression + */ + @Check + public void checkDoStatement(DoStatement statement) { + TypeExpression typeOfCondition = new TypeUtils().getTypeOfExpression(statement.getCondition()) ; + if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfCondition.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + if (TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean).isCompatibleWithMe(typeOfCondition) == 0) { + String errorMessage = "Expecting an expression of type Boolean. Found an expression of type " + typeOfCondition.getLabel() ; + error(errorMessage, AlfPackage.eINSTANCE.getDoStatement_Condition()) ; + } + } + } + + /** + * @param statement ForStatement + * + * Checks the following rule: + * 1. Loop variable names must not be available (i.e., not used in the scope of the statement) + * 2. Loop variable names must not duplicate (i.e., two loop variables for this statement must not have the same name) + * 3. if the loop variable definition uses the syntax option with keyword "in", following rules must be checked: + * 3.a. if only expression1 is specified, the upper bound of expression 1 must be greater than 1 + * 3.b. if both expression1 and expression2 are specified, they must be type compatible and represent number values (TODO: check other constraints in the spec) + * 4. if the loop variable definition uses the syntax option with keyword ":", following rules must be checked: + * 4.a. type must be resolved + * 4.b. the domain value "expression" must be type-compatible with the variable and must be a collection + */ + @Check + public void checkForStatement(ForStatement statement) { + // 1. Loop variable names must not be available (i.e., not used in the scope of the statement) + AlfPartialScope variablesScope = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(statement) ; + Map<String, Integer> declaredVariables = new HashMap<String, Integer>() ; + for (LoopVariableDefinition loopVariable : statement.getControl().getLoopVariableDefinition()) { + Integer variableDefinitionCounter = declaredVariables.get(loopVariable.getName()) ; + if (variableDefinitionCounter == null) { + declaredVariables.put(loopVariable.getName(), new Integer(1)) ; + } + else { + declaredVariables.put(loopVariable.getName(), variableDefinitionCounter.intValue() + 1) ; + } + List<EObject> visibleVariables = variablesScope.resolveByName(loopVariable.getName()) ; + if (! visibleVariables.isEmpty()) { // potentially conflicting name + if (variablesScope.getScopingLevel(visibleVariables.get(0)) == 0) { + // There is actually a conflict + error("Local name " + loopVariable.getName() + " is not available" , + loopVariable, + AlfPackage.eINSTANCE.getLocalNameDeclarationStatement_VarName(), + statement.getControl().getLoopVariableDefinition().indexOf(loopVariable)) ; + } + } + } + + // 2. Loop variable names must not duplicate (i.e., two loop variables for this statement must not have the same name) + boolean duplicationFound = false ; + for (Integer i : declaredVariables.values()) { + if (i.intValue() > 1) + duplicationFound = true ; + } + if (duplicationFound) { + error("Duplicate loop variable definitions" , AlfPackage.eINSTANCE.getForStatement_Control()) ; + } + + for (LoopVariableDefinition loopVariable : statement.getControl().getLoopVariableDefinition()) { + // 3. if the loop variable definition uses the syntax option with keyword "in", following rules must be checked: + // 3.a. if only expression1 is specified, the upper bound of expression 1 must be greater than 1 + if (loopVariable.getExpression1() != null && loopVariable.getExpression2() == null) { + TypeExpression typeOfExpression1 = new TypeUtils().getTypeOfExpression(loopVariable.getExpression1()) ; + if (typeOfExpression1.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfExpression1.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + int upperBound = typeOfExpression1.getMultiplicity().getUpperBound() ; + if (! (upperBound > 1 || upperBound == -1)) { + String errorMessage = "Invalid upper bound multiplicity (" + upperBound + "). A collection is expected." ; + error(errorMessage, loopVariable, AlfPackage.eINSTANCE.getLoopVariableDefinition_Expression1(), INSIGNIFICANT_INDEX) ; + } + } + } + // 3.b. if both expression1 and expression2 are specified, they must be type compatible and represent number values (TODO: check other constraints in the spec) + else if (loopVariable.getExpression1() != null && loopVariable.getExpression2() != null) { + TypeExpression typeOfExpression1 = new TypeUtils().getTypeOfExpression(loopVariable.getExpression1()) ; + boolean errorInExpressions = false ; + if (typeOfExpression1.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfExpression1.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorInExpressions = true ; + } + TypeExpression typeOfExpression2 = new TypeUtils().getTypeOfExpression(loopVariable.getExpression2()) ; + if (typeOfExpression2.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfExpression2.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorInExpressions = true ; + } + if (! errorInExpressions) { // both Expression must be type compatible and resolve to a scalar number value + TypeFacade typeFacadeOfExpression1 = typeOfExpression1.getTypeFacade() ; + int upperBoundExpression1 = typeOfExpression1.getMultiplicityFacade().getUpperBound() ; + String errorMessageForExpression1 = "" ; + if (!isANumberType(typeFacadeOfExpression1)) { + if (upperBoundExpression1 > 1 || upperBoundExpression1 == -1) + errorMessageForExpression1 += "A scalar number value is expected" ; + else + errorMessageForExpression1 += "A number value is expected" ; + } + else { + if (upperBoundExpression1 > 1 || upperBoundExpression1 == -1) + errorMessageForExpression1 += "A scalar value is expected" ; + } + if (!(errorMessageForExpression1.length() == 0)) { + error(errorMessageForExpression1, loopVariable, AlfPackage.eINSTANCE.getLoopVariableDefinition_Expression1(), INSIGNIFICANT_INDEX) ; + } + TypeFacade typeFacadeOfExpression2 = typeOfExpression2.getTypeFacade() ; + int upperBoundExpression2 = typeOfExpression2.getMultiplicityFacade().getUpperBound() ; + String errorMessageForExpression2 = "" ; + if (!isANumberType(typeFacadeOfExpression2)) { + if (upperBoundExpression2 > 1 || upperBoundExpression2 == -1) + errorMessageForExpression2 += "A scalar number value is expected" ; + else + errorMessageForExpression2 += "A number value is expected" ; + } + else { + if (upperBoundExpression2 > 1 || upperBoundExpression2 == -1) + errorMessageForExpression2 += "A scalar value is expected" ; + } + if (!(errorMessageForExpression2.length() == 0)) { + error(errorMessageForExpression2, loopVariable, AlfPackage.eINSTANCE.getLoopVariableDefinition_Expression2(), INSIGNIFICANT_INDEX) ; + } + } + } + //4. if the loop variable definition uses the syntax option with keyword ":", following rules must be checked: + else if (loopVariable.getType() != null) { + // 4.a. type must be resolved + TypeFacade typeOfVariable = TypeFacadeFactory.eInstance.createVoidFacade(loopVariable.getType()) ; + if (typeOfVariable instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfVariable ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { // 4.b. the domain value "expression" must be type-compatible with the variable and must be a collection + TypeExpression typeOfDomain = new TypeUtils().getTypeOfExpression(loopVariable.getExpression()) ; + if (typeOfDomain.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfDomain.getTypeFacade() ; + error (error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + int upperBound = typeOfDomain.getMultiplicity().getUpperBound() ; + if (! (upperBound > 1 || upperBound == -1)) { + String errorMessage = "Invalid upper bound multiplicity (" + upperBound + "). A collection is expected." ; + error(errorMessage, loopVariable, AlfPackage.eINSTANCE.getLoopVariableDefinition_Expression(), INSIGNIFICANT_INDEX) ; + } + if (typeOfVariable.isCompatibleWithMe(typeOfDomain.getTypeFacade()) == 0) { + String errorMessage = "Cannot convert from " + typeOfDomain.getTypeFacade().getLabel() + " to " + typeOfVariable.getLabel() ; + error(errorMessage, loopVariable, AlfPackage.eINSTANCE.getLoopVariableDefinition_Type(), INSIGNIFICANT_INDEX) ; + } + } + } + } + } + } + + /** + * @param statement + * + * Checks the following rule: + * 1. That a return value is actually expected from the context of the ALF specification + * 2. If a return value is expected, the returned value must be type/multiplicity compatible + * 3. There must be no statement in the containing statement sequence after the return statement. + */ + @Check + public void checkReturnStatement(ReturnStatement statement) { + // 1. Checks that a return value is actually expected from the context of the ALF specification + boolean returnStatementExpected = AlfScopeProvider.scopingTool.isAReturnStatementExpected(statement) ; + if (returnStatementExpected == false) { + String errorMessage = "No return statement expected" ; + error (errorMessage, AlfPackage.eINSTANCE.getReturnStatement_Expression()) ; + } + else { + // 2. If a return value is expected, the returned value must be type/multiplicity compatible + TypeExpression expectedReturnType = AlfScopeProvider.scopingTool.getExpectedReturnType(statement) ; + TypeExpression actualReturnType = new TypeUtils().getTypeOfExpression(statement.getExpression()) ; + if (actualReturnType.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)actualReturnType.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + if (expectedReturnType.isCompatibleWithMe(actualReturnType) == 0) { + String errorMessage = "An expression of type " + expectedReturnType.getLabel() + " is expected. Found an expression of type " + actualReturnType.getLabel() ; + error (errorMessage, AlfPackage.eINSTANCE.getReturnStatement_Expression()) ; + } + } + } + // 3. There must be no statement (in the containing statement sequence) after the return statement. + EObject cddStatementSequence = statement.eContainer() ; + DocumentedStatement contextDocumentedStatement = null ; + while (cddStatementSequence != null && + ! ((cddStatementSequence instanceof StatementSequence) || (cddStatementSequence instanceof NonEmptyStatementSequence))) { + if (contextDocumentedStatement == null && cddStatementSequence instanceof DocumentedStatement) + contextDocumentedStatement = (DocumentedStatement)cddStatementSequence ; + cddStatementSequence = cddStatementSequence.eContainer() ; + } + if (cddStatementSequence != null && contextDocumentedStatement != null) { + int statementIndex = 0 ; + int numberOfStatements = 0 ; + if (cddStatementSequence instanceof StatementSequence) { + statementIndex = ((StatementSequence)cddStatementSequence).getStatements().indexOf(contextDocumentedStatement) ; + numberOfStatements = ((StatementSequence)cddStatementSequence).getStatements().size() ; + } + else { + statementIndex = ((NonEmptyStatementSequence)cddStatementSequence).getStatement().indexOf(contextDocumentedStatement) ; + numberOfStatements = ((NonEmptyStatementSequence)cddStatementSequence).getStatement().size() ; + } + String errorMessage = "The statement cannot be reached" ; + for (int i = statementIndex + 1 ; i < numberOfStatements ; i++) { + DocumentedStatement current = null ; + if (cddStatementSequence instanceof StatementSequence) + current = ((StatementSequence)cddStatementSequence).getStatements().get(i) ; + else + current = ((NonEmptyStatementSequence)cddStatementSequence).getStatement().get(i) ; + error(errorMessage, current, AlfPackage.eINSTANCE.getDocumentedStatement_Statement(), INSIGNIFICANT_INDEX) ; + } + } + } + + + /** + * @param statement + * + * Checks the following rules: + * 1. Checks that the context classifier is active + * 2. Each AcceptClause.name (if specified) must be available. + * 3. There must be a Reception for each Signal identified in each AcceptClause.qualifiedNameList + * 4. Each Signal must be used only once + */ + @Check + public void checkAcceptStatement(AcceptStatement statement) { + //1. Checks that the context classifier is active + if (! (contextClassifier instanceof Class) || !((Class)contextClassifier).isActive()) { + error("The context classifier must be an active class", AlfPackage.eINSTANCE.getAcceptStatement_Clause()) ; + } + + //2. Each AcceptClause.name (if specified) must be available. + AlfPartialScope vppScope = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(statement) ; + if (statement.getClause().getName() != null ) { + List<EObject> visibleElements = vppScope.resolveByName(statement.getClause().getName()) ; + if (! visibleElements.isEmpty() && vppScope.getScopingLevel(visibleElements.get(0)) == 0) { + String errorMessage = "Local name " + statement.getClause().getName() + " is not available" ; + error(errorMessage, statement.getClause(), AlfPackage.eINSTANCE.getAcceptClause_Name(), INSIGNIFICANT_INDEX) ; + } + } + if (statement.getCompoundAccept() != null) { + for (AcceptBlock block : statement.getCompoundAccept().getAcceptBlock()) { + if (block.getClause() != null && block.getClause().getName() != null) { + List<EObject> visibleElements = vppScope.resolveByName(block.getClause().getName()) ; + if (! visibleElements.isEmpty() && vppScope.getScopingLevel(visibleElements.get(0)) == 0) { + String errorMessage = "Local name " + block.getClause().getName() + " is not available" ; + error(errorMessage, block.getClause(), AlfPackage.eINSTANCE.getAcceptClause_Name(), INSIGNIFICANT_INDEX) ; + } + } + } + } + + //3. There must be a Reception for each Signal identified in each AcceptClause.qualifiedNameList + AlfPartialScope signalReceptionScope = AlfScopeProvider.scopingTool.getVisibleSignalReceptions(statement) ; + List<TypeFacade> signalReceptionTypeFacade = new ArrayList<TypeFacade>() ; + for (List<EObject> l : signalReceptionScope.getScopeDetails()) { + for (EObject m : l) { + signalReceptionTypeFacade.add(TypeFacadeFactory.eInstance.createTypeFacade(m)) ; + } + } + Map<Classifier, List<QualifiedNameWithBinding>> allReferencedSignals= new HashMap<Classifier, List<QualifiedNameWithBinding>>() ; + if (statement.getClause().getQualifiedNameList() != null) { + QualifiedNameList list = statement.getClause().getQualifiedNameList() ; + int index = 0 ; + for (QualifiedNameWithBinding qualifiedName : list.getQualifiedName()) { + TypeFacade type = TypeFacadeFactory.eInstance.createVoidFacade(qualifiedName) ; + if (type instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)type ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + Classifier actualReferencedClassifier = type.extractActualType() ; + List<QualifiedNameWithBinding> existingReferences = allReferencedSignals.get(actualReferencedClassifier) ; + if (existingReferences == null) { + existingReferences = new ArrayList<QualifiedNameWithBinding>() ; + + } + existingReferences.add(qualifiedName) ; + allReferencedSignals.put(actualReferencedClassifier, existingReferences) ; + boolean found = false ; + Iterator<TypeFacade> i = signalReceptionTypeFacade.iterator() ; + while (i.hasNext() && !found) { + TypeFacade current = i.next() ; + if (current.isCompatibleWithMe(type)!=0) + found = true ; + } + if (!found) { + String errorMessage = "The context classifier does not define any reception for " + type.getLabel() ; + error(errorMessage, list, AlfPackage.eINSTANCE.getQualifiedNameList_QualifiedName(), index) ; + } + } + index ++ ; + } + } + + //4. Each Signal must be used only once + for (Classifier key : allReferencedSignals.keySet()) { + List<QualifiedNameWithBinding> referencesToKey = allReferencedSignals.get(key) ; + if (referencesToKey.size()>1) { + for (QualifiedNameWithBinding qualifiedName : referencesToKey) { + String errorMessage = "No signal may be named in more than one accept clause" ; + QualifiedNameList containingList = (QualifiedNameList)qualifiedName.eContainer() ; + int index = containingList.getQualifiedName().indexOf(qualifiedName) ; + error(errorMessage, containingList, AlfPackage.eINSTANCE.getQualifiedNameList_QualifiedName(), index - 1 ) ; + } + } + } + } + + + /** + * @param statement + * + * Checks the following rules: + * 1. The static type of the target expression must be a Class + * and it must evaluate to a single object + * 2. All qualified names in from or to lists must resolve to classes + * 3. All the classes in the from and to lists must be subclasses of the static type of the target expression + * 4. None of them may have a common superclass of the static type of the target expression (i.e., disjoint subclasses) + * + */ + @Check + public void checkClassifyStatement(ClassifyStatement statement) { + // 1. The static type of the target expression must be a Class... + Classifier actualStaticType = null ; + TypeExpression staticType = new TypeUtils().getTypeOfExpression(statement.getExpression()) ; + boolean errorFound = false ; + if (staticType.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)staticType.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorFound = true ; + } + else { + actualStaticType = staticType.getTypeFacade().extractActualType() ; + } + if (actualStaticType == null || !(actualStaticType instanceof Class)) { + String errorMessage = "The type of the target expression must be a class" ; + error(errorMessage, AlfPackage.eINSTANCE.getClassifyStatement_Expression()) ; + errorFound = true ; + } + else { + //... and it must evaluate to a single object + int upperBound = staticType.getMultiplicityFacade().getUpperBound() ; + if (upperBound > 1 || upperBound == -1) { + String errorMessage = "The target expression must evaluate to a single object" ; + error(errorMessage, AlfPackage.eINSTANCE.getClassifyStatement_Expression()) ; + errorFound = true ; + } + } + + // 2. All qualified names in from or to lists must resolve to classes + ClassificationClause classificationClause = statement.getClause() ; + List<Class> fromClasses = new ArrayList<Class>() ; + List<Class> toClasses = new ArrayList<Class>() ; + if (classificationClause == null) + return ; + boolean isAReclassifyFromAll = false ; + if (classificationClause.getClassifyFromClause() == null && + classificationClause.getClassifyToClause() == null && + classificationClause.getReclassyAllClause() == null) + return ; + if (classificationClause.getReclassyAllClause() != null) + // nothing to do with the from list + isAReclassifyFromAll = true ; + if (classificationClause.getClassifyFromClause() != null) { + ClassificationFromClause fromClause = classificationClause.getClassifyFromClause() ; + for (QualifiedNameWithBinding name : fromClause.getQualifiedNameList().getQualifiedName()) { + TypeFacade type = TypeFacadeFactory.eInstance.createVoidFacade(name) ; + if (type instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)type ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorFound = true ; + } + else { + Classifier actualType = type.extractActualType(type) ; + if (actualType == null || !(actualType instanceof Class)) { + String errorMessage = "All types in the 'from' list must be Classes" ; + int index = fromClause.getQualifiedNameList().getQualifiedName().indexOf(name) ; + error(errorMessage, + fromClause.getQualifiedNameList(), + AlfPackage.eINSTANCE.getQualifiedNameList_QualifiedName(), + index) ; + } + else { + fromClasses.add((Class)actualType) ; + } + } + } + } + if (classificationClause.getClassifyToClause() != null) { + ClassificationToClause toClause = classificationClause.getClassifyToClause() ; + for (QualifiedNameWithBinding name : toClause.getQualifiedNameList().getQualifiedName()) { + TypeFacade type = TypeFacadeFactory.eInstance.createVoidFacade(name) ; + if (type instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)type ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorFound = true ; + } + else { + Classifier actualType = type.extractActualType(type) ; + if (actualType == null || !(actualType instanceof Class)) { + String errorMessage = "All types in the 'from' list must be Classes" ; + int index = toClause.getQualifiedNameList().getQualifiedName().indexOf(name) ; + error(errorMessage, + toClause.getQualifiedNameList(), + AlfPackage.eINSTANCE.getQualifiedNameList_QualifiedName(), + index) ; + } + else { + toClasses.add((Class)actualType) ; + } + } + } + } + + + // 3. All the classes in the from and to lists must be subclasses of the static type of the target expression + if (errorFound) + return ; // not necessary to check the remaining + List<Classifier> fromGenerals = new ArrayList<Classifier>() ; + List<Classifier> toGenerals = new ArrayList<Classifier>() ; + if (actualStaticType != null && !errorFound) { + String errorMessage = "All classes in the 'from' list must be subclasses of the target expression type" ; + int index = 0 ; + for (Class c : fromClasses) { + if (! c.allParents().contains(actualStaticType)) { + error(errorMessage, + classificationClause.getClassifyFromClause(), + AlfPackage.eINSTANCE.getClassificationFromClause_QualifiedNameList(), + index) ; + errorFound = true ; + } + fromGenerals.addAll(c.allParents()) ; + index++ ; + } + errorMessage = "All classes in the 'to' list must be subclasses of the target expression type" ; + index = 0 ; + for (Class c : toClasses) { + if (! c.allParents().contains(actualStaticType)) { + error(errorMessage, + classificationClause.getClassifyToClause(), + AlfPackage.eINSTANCE.getClassificationToClause_QualifiedNameList(), + index) ; + errorFound = true ; + } + index++ ; + toGenerals.addAll(c.allParents()) ; + } + } + + // 4. None of them may have a common superclass of the static type of the target expression (i.e., disjoint subclasses) + if (errorFound) + return ; // not necessary to go further + fromGenerals.retainAll(toGenerals) ; + for (Classifier c : fromGenerals) { + if (c.allParents().contains(actualStaticType)) { + String errorMessage = "Superclasses of classes in 'to' and 'from' lists must be disjoint subclasses of the target expression type" ; + error(errorMessage, AlfPackage.eINSTANCE.getClassifyStatement_Clause()) ; + return ; + } + } + + } + + /** + * @param statement + * Checks the following rules: + * 1. The statement must respect construction rules of: + * 1.a Invocation, or + * 1.b Variable declaration, or + * 1.c Assignment expression + * 2. According to the construction rule, delegate to the appropriate check method + */ + @Check + public void checkInvocationOrAssignmentOrDeclarationStatement(InvocationOrAssignementOrDeclarationStatement statement) { + //1. The statement must respect construction rules of: + // 1.b Variable declaration + if (statement.getVariableDeclarationCompletion() != null) { + checkVariableDeclarationStatement(statement) ; + } + // 1.c Assignment expression + else if (statement.getAssignmentCompletion() != null) { + checkAssignmentExpression(statement) ; + } + // 1.a Invocation or prefix or suffix + else { + checkInvocationOrPrefixOrSuffixStatement(statement) ; + } + } + + /** + * @param statement + * Checks the following rules: + * 1. typePart_OR_assignedPart_OR_invocationPart must have an invocation completion, or a postfixOp, or a prefixOp + * 2. if it is an invocation: + * 2.a The name must resolve to a Behavior or an Operation + * 2.b Arguments must be type compatibles with the parameters of referenced behavior or operation + * 3. if it is a prefixOp: + * 3.a the name must resolve to an assignable property, parameter or local variable + * 3.b the operator must be available for the type of the nameExpression + * 4. if it is a postfixOp: + * 4.a the name must resolve to an assignable property, parameter or local variable + * 4.b the operator must be available for the type of the nameExpression + */ + private void checkInvocationOrPrefixOrSuffixStatement(InvocationOrAssignementOrDeclarationStatement statement) { + // 1. typePart_OR_assignedPart_OR_invocationPart must have an invocation completion, or a postfixOp, or a prefixOp + boolean isAnInvocation = statement.getTypePart_OR_assignedPart_OR_invocationPart().getInvocationCompletion() != null ; + boolean isAPrefixExpression = statement.getTypePart_OR_assignedPart_OR_invocationPart().getPrefixOp() != null ; + boolean isAPostfixExpression = statement.getTypePart_OR_assignedPart_OR_invocationPart().getPostfixOp() != null ; + boolean hasASuffix = statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() != null ; + int resolvedKindOfExpression = 0 ; + resolvedKindOfExpression += isAnInvocation ? 1 : 0 ; + resolvedKindOfExpression += isAPrefixExpression ? 1 : 0 ; + resolvedKindOfExpression += isAPostfixExpression ? 1 : 0 ; + resolvedKindOfExpression += hasASuffix ? 1 : 0 ; + if ((resolvedKindOfExpression > 1 && !hasASuffix) || resolvedKindOfExpression==0) { + String errorMessage = "An invocation expression, OR a prefix expression, OR a postfix expression is expected." ; + error(errorMessage, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + return ; + } + + //2. if it is an invocation: + if (isAnInvocation || hasASuffix) { + // 2.a The name must resolve to a Variable, a Parameter, a Property, a Behavior or an Operation (TODO: can also be an association) + NameExpression varOrParamOrPropOrOpOrBehav = statement.getTypePart_OR_assignedPart_OR_invocationPart() ; + TypeExpression typeOfPrefix = new TypeUtils().getTypeOfNameExpression(varOrParamOrPropOrOpOrBehav) ; + if (typeOfPrefix.getTypeFacade() != null && typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfPrefix.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + return ; + } + if (hasASuffix) { + // The last suffix must be an invocation + SuffixExpression suffix = statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() ; + SuffixExpression lastSuffix = suffix ; + boolean suffixHasASuffix = false ; + do { + suffixHasASuffix = false ; + for (Iterator<EObject> content = suffix.eContents().iterator() ; content.hasNext() && !suffixHasASuffix ; ) { + EObject cddSuffix = content.next() ; + if (cddSuffix instanceof SuffixExpression) { + lastSuffix = (SuffixExpression)cddSuffix ; + suffixHasASuffix = true ; + } + } + if (suffixHasASuffix) + suffix = lastSuffix ; + } while (suffixHasASuffix) ; + if (lastSuffix instanceof PropertyCallExpression) { + error("An invocation is expected", + AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + return ; + } + } + //} + } + + // 3. if it is a prefixOp: or // 4. if it is a postfixOp: + else if (isAPrefixExpression || isAPostfixExpression) { + TypeExpression typeOfAssignedElement = new TypeUtils().getTypeOfNameExpression(statement.getTypePart_OR_assignedPart_OR_invocationPart()) ; + if (typeOfAssignedElement.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfAssignedElement.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + return ; + } + //1. The assigned part must be assignable, i.e.: + if (statement.getTypePart_OR_assignedPart_OR_invocationPart().getPath() != null || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getInvocationCompletion() != null + && statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() == null) || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getSequenceConstructionCompletion() != null) || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getId()==null) || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getId().length() == 0)) { + error("The assigned part must resolve to an assignable property, parameter or local variable", + AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + return ; + } + //1.a It must resolve to a property, or + //1.b It must resolve to a local variable, or + //1.c It must resolve to an out or inout parameter + if (statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() == null) { + AlfPartialScope varParamPropScope = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(statement) ; + EObject resolved = varParamPropScope.resolveByName(statement.getTypePart_OR_assignedPart_OR_invocationPart().getId()).get(0) ; + String potentialAssignmentError = AssignmentPolicy.eInstance.isAssignable(resolved) ; + if (!(potentialAssignmentError.length() == 0)) { + error(potentialAssignmentError, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + return ; + } + } + else {// a suffix is specified + // The last suffix must be a property call expression + SuffixExpression suffix = statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() ; + SuffixExpression lastSuffix = suffix ; + boolean suffixHasASuffix = false ; + do { + suffixHasASuffix = false ; + for (Iterator<EObject> content = suffix.eContents().iterator() ; content.hasNext() && !suffixHasASuffix ; ) { + EObject cddSuffix = content.next() ; + if (cddSuffix instanceof SuffixExpression) { + lastSuffix = (SuffixExpression)cddSuffix ; + suffixHasASuffix = true ; + } + } + if (suffixHasASuffix) + suffix = lastSuffix ; + } while (suffixHasASuffix) ; + if (! (lastSuffix instanceof PropertyCallExpression)) { + error("The assigned part must resolve to an assignable property, parameter or local variable", + AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + return ; + } + } + + TypeExpression integerExpression = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._integer) ; + TypeExpression naturalExpression = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._natural) ; + TypeExpression unlimitedExpression = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._unlimited) ; + String operator = isAPrefixExpression ? statement.getTypePart_OR_assignedPart_OR_invocationPart().getPrefixOp() : statement.getTypePart_OR_assignedPart_OR_invocationPart().getPostfixOp() ; + EStructuralFeature feature = isAPrefixExpression ? AlfPackage.eINSTANCE.getNameExpression_PrefixOp() : AlfPackage.eINSTANCE.getNameExpression_PostfixOp() ; + if (! (integerExpression.isCompatibleWithMe(typeOfAssignedElement)!= 0 || + naturalExpression.isCompatibleWithMe(typeOfAssignedElement)!= 0 || + unlimitedExpression.isCompatibleWithMe(typeOfAssignedElement)!= 0)) { + error("Operator " + operator + " does not apply to " + typeOfAssignedElement.getLabel() , + statement.getTypePart_OR_assignedPart_OR_invocationPart(), + feature, + INSIGNIFICANT_INDEX) ; + } + } + } + + + /** + * @param statement + * + * Checks the following rule: + * 1. typePart_OR_assignedPart_OR_invocationPart must resolve to a type + * 2. the variable name must be available + * 3. initValue must respect the following sub-rules: + * 3.a the type of the expression must be compatible with the type of the variable + * 3.b the assignment operator must be '=' + */ + private void checkVariableDeclarationStatement(InvocationOrAssignementOrDeclarationStatement statement) { + // 1. typePart_OR_assignedPart_OR_invocationPart must resolve to a type + VoidFacade actualVariableType = null ; + TypeFacade cddVariableType = TypeFacadeFactory.eInstance.createVoidFacade(statement.getTypePart_OR_assignedPart_OR_invocationPart()) ; + if (cddVariableType instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)cddVariableType ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + } + else { + actualVariableType = (VoidFacade)cddVariableType ; + } + VariableDeclarationCompletion declaration = statement.getVariableDeclarationCompletion() ; + TypeExpression variableTypeExpression = null ; + if (actualVariableType != null) { + if (declaration.isMultiplicityIndicator()) + variableTypeExpression = TypeExpressionFactory.eInstance.createTypeExpression(actualVariableType, 0, -1, false, true) ; + else + variableTypeExpression = TypeExpressionFactory.eInstance.createTypeExpression(actualVariableType, 1, 1, true, false) ; + } + + // 2. the variable name must be available + AlfPartialScope vppScope = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(statement) ; + if (declaration.getVariableName() != null ) { + List<EObject> visibleElements = vppScope.resolveByName(declaration.getVariableName()) ; + if (! visibleElements.isEmpty() && vppScope.getScopingLevel(visibleElements.get(0)) == 0) { + String errorMessage = "Local name " + declaration.getVariableName() + " is not available" ; + error(errorMessage, declaration, AlfPackage.eINSTANCE.getVariableDeclarationCompletion_VariableName(), INSIGNIFICANT_INDEX) ; + } + } + + //3. initValue must respect the following sub-rules: + if (declaration.getInitValue() != null && declaration.getInitValue().getRightHandSide() != null) { + TypeExpression typeOfInit = new TypeUtils().getTypeOfSequenceElement(declaration.getInitValue().getRightHandSide()) ; + if (typeOfInit == null) { + String errorMessage = "Init value is missing" ; + error(errorMessage, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_VariableDeclarationCompletion()) ; + return ; + } + if (typeOfInit.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfInit.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + return ; + } + if (variableTypeExpression != null) { + // 3.a the type of the expression must be compatible with the type of the variable + if (variableTypeExpression.isCompatibleWithMe(typeOfInit) == 0) { + String errorMessage = "Expecting an expression of type " + variableTypeExpression.getLabel() + + ". Found an expression of type " + typeOfInit.getLabel() + "." ; + error(errorMessage, + declaration.getInitValue(), + AlfPackage.eINSTANCE.getAssignmentCompletion_RightHandSide(), + INSIGNIFICANT_INDEX) ; + } + // 3.b the assignment operator must be '=' + else if (declaration.getInitValue().getOp() != AssignmentOperator.ASSIGN) { + String errorMessage = "Expecting assignment operator '='" ; + error(errorMessage, + declaration.getInitValue(), + AlfPackage.eINSTANCE.getAssignmentCompletion_Op(), + INSIGNIFICANT_INDEX) ; + } + } + } + } + + + /** + * + * @param statement + * + * Checks the following rules: + * 1. The left part must be assignable, i.e.: + * 1.a It must resolve to a property, or + * 1.b It must resolve to a local variable, or + * 1.c It must resolve to an out or inout parameter + * 1.d It resolves to an association end TODO: Not supported yet + * 2. If the assignment operator is "=", the right part must be type compatible with the left part + * 3. If the assignment operator is not "=" (e.g. +=, -=, etc.), there must be a matching signature for this operator + */ + private void checkAssignmentExpression(InvocationOrAssignementOrDeclarationStatement statement) { + boolean errorInExpressions = false ; + // first infer type of the left part + TypeExpression typeOfLeft = new TypeUtils().getTypeOfNameExpression(statement.getTypePart_OR_assignedPart_OR_invocationPart()) ; + if (typeOfLeft.getTypeFacade() == null || typeOfLeft.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfLeft.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorInExpressions = true ; + } + // then infer type of the right part + TypeExpression typeOfRight = null ; + if (statement.getAssignmentCompletion().getRightHandSide() != null) { + typeOfRight = new TypeUtils().getTypeOfSequenceElement(statement.getAssignmentCompletion().getRightHandSide()) ; + if (typeOfRight == null || typeOfRight.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfRight.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + errorInExpressions = true ; + } + } + if (errorInExpressions) // not necessary to validate further + return ; + + //1. The left part must be assignable, i.e.: + if (statement.getTypePart_OR_assignedPart_OR_invocationPart().getPath() != null || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getInvocationCompletion() != null + && statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() == null) || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getPrefixOp()!=null) || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getPostfixOp()!=null) || + (statement.getTypePart_OR_assignedPart_OR_invocationPart().getSequenceConstructionCompletion() != null)) { + if (statement.getTypePart_OR_assignedPart_OR_invocationPart().getSequenceConstructionCompletion() != null) { + if (statement.getTypePart_OR_assignedPart_OR_invocationPart().getSequenceConstructionCompletion().getAccessCompletion() != null) + return ; + } + error("The left part of the assignment must resolve to an assignable property, parameter or local variable", + AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + // NOTE: this an approximation. Cf. => rule 1.d It resolves to an association end TODO: Not supported yet + return ; + } + //1.a It must resolve to a property, or + //1.b It must resolve to a local variable, or + //1.c It must resolve to an out or inout parameter + if (statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() == null) { + AlfPartialScope varParamPropScope = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(statement) ; + EObject resolved = varParamPropScope.resolveByName(statement.getTypePart_OR_assignedPart_OR_invocationPart().getId()).get(0) ; + String potentialAssignmentError = AssignmentPolicy.eInstance.isAssignable(resolved) ; + if (!(potentialAssignmentError.length() == 0)) { + error(potentialAssignmentError, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + } + } + else {// a suffix is specified + // The last suffix must be a property call expression + SuffixExpression suffix = statement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() ; + SuffixExpression lastSuffix = suffix ; + boolean suffixHasASuffix = false ; + do { + suffixHasASuffix = false ; + for (Iterator<EObject> content = suffix.eContents().iterator() ; content.hasNext() && !suffixHasASuffix ; ) { + EObject cddSuffix = content.next() ; + if (cddSuffix instanceof SuffixExpression) { + lastSuffix = (SuffixExpression)cddSuffix ; + suffixHasASuffix = true ; + } + } + if (suffixHasASuffix) + suffix = lastSuffix ; + } while (suffixHasASuffix) ; + if (! (lastSuffix instanceof PropertyCallExpression)) { + error("The left part of the assignment must resolve to an assignable property, parameter or local variable", + AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ; + return ; + } + } + + // 2. If the assignment operator is "=", the right part must be type compatible with the left part + if (statement.getAssignmentCompletion().getOp() == AssignmentOperator.ASSIGN) { + if (typeOfRight.getTypeFacade() == TypeUtils._undefined) { + String errorMessage = "Right part is untyped" ; + error(errorMessage, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_AssignmentCompletion()) ; + } + else if (typeOfLeft.isCompatibleWithMe(typeOfRight) == 0) { + String errorMessage = "Cannot assign " + typeOfRight.getLabel() + " to " + typeOfLeft.getLabel() ; + error(errorMessage, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_AssignmentCompletion()) ; + } + } + else { // 3. If the assignment operator is not "=" (e.g. +=, -=, etc.), there must be a matching signature for this operator + String assignmentOp = assignmentOpToString(statement.getAssignmentCompletion().getOp()) ; + List<SignatureFacade> candidates = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(assignmentOp) ; + List<TypeExpression> arguments = new ArrayList<TypeExpression>() ; + arguments.add(typeOfLeft) ; + arguments.add(typeOfRight) ; + List<SignatureFacade> matchingSignatures = SignatureFacade.findNearestSignature(arguments, candidates) ; + if (matchingSignatures.isEmpty()) { + String errorMessage = "Operator " + assignmentOp + " does not apply to arguments (" ; + boolean first = true ; + for (TypeExpression argType : arguments) { + if (!first) + errorMessage += ", " ; + else + first = false ; + errorMessage += argType.getLabel() ; + } + errorMessage += ")" ; + error(errorMessage, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_AssignmentCompletion()) ; + } + } + } + + /** + * @param statement + * + * Checks the following rule: + * 1. The associated SuperInvocationExpression must be valid + */ + @Check + public void checkSuperInvocationStatement(SuperInvocationStatement statement) { + TypeExpression typeOfSuperInvocationExp = new TypeUtils().getTypeOfSuperInvocationExpression(statement.get_super()) ; + if (typeOfSuperInvocationExp.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfSuperInvocationExp.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + return ; + } + } + + /** + * @param statement + * + * Checks the following rules: + * 1. The associated ThisExpression must be valid + * 2. If an assignment is specified: + * 2.a The left part must resolve to a property call expression + * 2.b If the assignment operator is "=", the right part must be type compatible with the left part + * 2.c If the assignment operator is not "=" (e.g. +=, -=, etc.), there must be a matching signature for this operator + * 3. If no assignment is specified, the suffix must resolve to an invocation + */ + @Check + public void checkThisInvocationStatement(ThisInvocationStatement statement) { + // 1. The associated ThisExpression must be valid + TypeExpression typeOfThisExpression = new TypeUtils().getTypeOfThisExpression(statement.get_this()) ; + if (typeOfThisExpression.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfThisExpression.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + // return ; + } + + // 2. If an assignment is specified + if (statement.getAssignmentCompletion() != null ) { + // 2.a The left part must resolve to a property call expression + if (statement.get_this().getSuffix() == null) { + error("A Property call expression is missing", + AlfPackage.eINSTANCE.getThisInvocationStatement__this()) ; + //return ; + } + else { + // The last suffix must be an invocation + SuffixExpression suffix = statement.get_this().getSuffix() ; + SuffixExpression lastSuffix = suffix ; + boolean suffixHasASuffix = false ; + do { + suffixHasASuffix = false ; + for (Iterator<EObject> content = suffix.eContents().iterator() ; content.hasNext() && !suffixHasASuffix ; ) { + EObject cddSuffix = content.next() ; + if (cddSuffix instanceof SuffixExpression) { + lastSuffix = (SuffixExpression)cddSuffix ; + suffixHasASuffix = true ; + } + } + if (suffixHasASuffix) + suffix = lastSuffix ; + } while (suffixHasASuffix) ; + if (!(lastSuffix instanceof PropertyCallExpression)) { + error("The expression should resolve to a Property", + AlfPackage.eINSTANCE.getThisInvocationStatement__this()) ; + //return ; + } + } + + TypeExpression typeOfAssignment = null ; + + if (statement.getAssignmentCompletion().getRightHandSide() == null) + return ; + else { + typeOfAssignment = new TypeUtils().getTypeOfSequenceElement(statement.getAssignmentCompletion().getRightHandSide()) ; + if (typeOfAssignment.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfAssignment.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + return ; + } + if (typeOfThisExpression.getTypeFacade() instanceof ErrorTypeFacade) + return ; + } + + // 2.b If the assignment operator is "=", the right part must be type compatible with the left part + if (statement.getAssignmentCompletion().getOp() == AssignmentOperator.ASSIGN) { + if (typeOfAssignment.getTypeFacade() == TypeUtils._undefined) { + String errorMessage = "Right part is untyped" ; + error(errorMessage, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_AssignmentCompletion()) ; + } + else if (typeOfThisExpression.isCompatibleWithMe(typeOfAssignment) == 0) { + String errorMessage = "Cannot assign " + typeOfAssignment.getLabel() + " to " + typeOfThisExpression.getLabel() ; + error(errorMessage, AlfPackage.eINSTANCE.getThisInvocationStatement_AssignmentCompletion()) ; + } + } + else { // 2.c If the assignment operator is not "=" (e.g. +=, -=, etc.), there must be a matching signature for this operator + String assignmentOp = assignmentOpToString(statement.getAssignmentCompletion().getOp()) ; + List<SignatureFacade> candidates = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(assignmentOp) ; + List<TypeExpression> arguments = new ArrayList<TypeExpression>() ; + arguments.add(typeOfThisExpression) ; + arguments.add(typeOfAssignment) ; + List<SignatureFacade> matchingSignatures = SignatureFacade.findNearestSignature(arguments, candidates) ; + if (matchingSignatures.isEmpty()) { + String errorMessage = "Operator " + assignmentOp + " does not apply to arguments (" ; + boolean first = true ; + for (TypeExpression argType : arguments) { + if (!first) + errorMessage += ", " ; + else + first = false ; + errorMessage += argType.getLabel() ; + } + errorMessage += ")" ; + error(errorMessage, AlfPackage.eINSTANCE.getThisInvocationStatement_AssignmentCompletion()) ; + } + } + } + else { // 3. If no assignment is specified, the suffix must resolve to an invocation + if (statement.get_this().getSuffix() == null) { + error("An invocation expression is expected", + AlfPackage.eINSTANCE.getThisInvocationStatement__this()) ; + return ; + } + else { + // The last suffix must be an invocation + SuffixExpression suffix = statement.get_this().getSuffix() ; + SuffixExpression lastSuffix = suffix ; + boolean suffixHasASuffix = false ; + do { + suffixHasASuffix = false ; + for (Iterator<EObject> content = suffix.eContents().iterator() ; content.hasNext() && !suffixHasASuffix ; ) { + EObject cddSuffix = content.next() ; + if (cddSuffix instanceof SuffixExpression) { + lastSuffix = (SuffixExpression)cddSuffix ; + suffixHasASuffix = true ; + } + } + if (suffixHasASuffix) + suffix = lastSuffix ; + } while (suffixHasASuffix) ; + if (lastSuffix instanceof PropertyCallExpression) { + error("An assignment is expected", + AlfPackage.eINSTANCE.getThisInvocationStatement__this()) ; + return ; + } + } + } + } + + /** + * @param statement + * + * Checks the following rule: + * 1. The InstanceCreationExpression must be valid + * 2. If a suffix is specified, it must resolve to an invocation + */ + @Check + public void checkInstanceCreationInvocationStatement(InstanceCreationInvocationStatement statement) { + // 1. The InstanceCreationExpression must be valid + TypeExpression typeOfInstanceCreationExpression = new TypeUtils().getTypeOfInstanceCreationExpression(statement.get_new()) ; + if (typeOfInstanceCreationExpression.getTypeFacade() instanceof ErrorTypeFacade) { + ErrorTypeFacade error = (ErrorTypeFacade)typeOfInstanceCreationExpression.getTypeFacade() ; + error(error.getLabel(), error.getErrorSource(), error.getStructuralFeature(), INSIGNIFICANT_INDEX) ; + return ; + } + + // 2. If a suffix is specified, it must resolve to an invocation + // The last suffix must be an invocation + SuffixExpression suffix = statement.get_new().getSuffix() ; + SuffixExpression lastSuffix = suffix ; + boolean suffixHasASuffix = false ; + do { + suffixHasASuffix = false ; + for (Iterator<EObject> content = suffix.eContents().iterator() ; content.hasNext() && !suffixHasASuffix ; ) { + EObject cddSuffix = content.next() ; + if (cddSuffix instanceof SuffixExpression) { + lastSuffix = (SuffixExpression)cddSuffix ; + suffixHasASuffix = true ; + } + } + if (suffixHasASuffix) + suffix = lastSuffix ; + } while (suffixHasASuffix) ; + if (lastSuffix instanceof PropertyCallExpression) { + error("An invocation is expected", + AlfPackage.eINSTANCE.getInstanceCreationInvocationStatement__new()) ; + return ; + } + } + + private String assignmentOpToString(AssignmentOperator operator) { + switch (operator) { + case ANDASSIGN: + return "&" ; + case DIVASSIGN: + return "/" ; + case LSHIFTASSIGN: + return "<<" ; + case MINUSASSIGN: + return "-" ; + case MODASSIGN: + return "%" ; + case MULTASSIGN: + return "*" ; + case ORASSIGN: + return "|" ; + case PLUSASSIGN: + return "+" ; + case RSHIFTASSIGN: + return ">>" ; + case URSHIFTASSIGN: + return ">>>" ; + case XORASSIGN: + return "^" ; + case ASSIGN: + return "=" ; + } + return "" ; // not reachable + } + + private boolean isANumberType(TypeFacade typeFacade) { + return TypeUtils._integer.isCompatibleWithMe(typeFacade) == 3 || + TypeUtils._natural.isCompatibleWithMe(typeFacade) == 3 || + TypeUtils._unlimited.isCompatibleWithMe(typeFacade) == 3 ; + } + + @Check + public void checkTemplateBindingInNameExpression(UnqualifiedName expression) { + if (expression.getTemplateBinding() != null) { + String errorMessage = "Template bindings are not supported in name expressions." ; // TODO + warning(errorMessage, AlfPackage.eINSTANCE.getUnqualifiedName_TemplateBinding()) ; + } + } + + @Check + public void checkTemplateBindingInQualifiedNameWithBinding(QualifiedNameWithBinding expression) { + //if (expression.getBinding() != null) { + // String errorMessage = "Template bindings are not supported in this version of the Alf editor." ; // TODO + // warning(errorMessage, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ; + //} + } +}
\ No newline at end of file diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/NamingUtils.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/NamingUtils.java new file mode 100644 index 00000000000..f273545ce48 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/NamingUtils.java @@ -0,0 +1,43 @@ +package org.eclipse.papyrus.alf.validation;
+
+public class NamingUtils {
+
+
+ /**
+ * Checks if a string represents a valid Java-name:
+ * - it starts with a letter or "_"
+ * - other characters are either letters, figures or "_"
+ *
+ * @param name
+ * @return true if the name is Java-compliant, false otherwise
+ */
+ public static boolean isJavaCompliant(String name) {
+ if (name.length() == 0)
+ return false ;
+ int firstChar = 0 ;
+ char[] dst = new char[name.length()] ;
+ name.getChars(0, name.length(), dst, firstChar) ;
+ if (dst[0] >= 'a' && dst[0] <= 'z')
+ ;
+ else if (dst [0] >= 'A' && dst[0] <= 'Z')
+ ;
+ else if (dst [0] == '_')
+ ;
+ else
+ return false ;
+ for (int i = 1 ; i<dst.length ; i++) {
+ if (dst[i] >= 'a' && dst[i] <= 'z')
+ ;
+ else if (dst [i] >= 'A' && dst[i] <= 'Z')
+ ;
+ else if (dst [i] >= '0' && dst[i] <= '9')
+ ;
+ else if (dst [i] == '_')
+ ;
+ else
+ return false ;
+ }
+ return true ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java new file mode 100644 index 00000000000..33482dd32d9 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/PredefinedBehaviorsAndTypesUtils.java @@ -0,0 +1,158 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.papyrus.alf.validation.typing.SignatureFacade;
+import org.eclipse.papyrus.alf.validation.typing.SignatureFacadeFactory;
+import org.eclipse.papyrus.alf.validation.typing.TypeExpressionFactory;
+import org.eclipse.papyrus.alf.validation.typing.TypeFacade;
+import org.eclipse.papyrus.alf.validation.typing.TypeFacadeFactory;
+import org.eclipse.papyrus.alf.validation.typing.TypeUtils;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.PackageImport;
+
+public class PredefinedBehaviorsAndTypesUtils {
+
+ private Map<String, List<SignatureFacade>> behaviorMap = new HashMap<String, List<SignatureFacade>>();
+ private Map<String, TypeFacade> typeMap = new HashMap<String, TypeFacade>() ;
+ private List<Behavior> behaviorInsertedAsElementImport = new ArrayList<Behavior>() ;
+ private List<Classifier> classifierInsertedAsElementImport = new ArrayList<Classifier>();
+ //private List<Behavior> predefinedCollectionFunctions = new ArrayList<Behavior>() ;
+ //private Map<String, SignatureFacade> predefinedCollectionFunctionsMap = new HashMap<String, SignatureFacade>() ;
+
+ public void init(org.eclipse.uml2.uml.Package library) {
+ behaviorMap = new HashMap<String, List<SignatureFacade>>();
+ typeMap = new HashMap<String, TypeFacade>() ;
+ behaviorInsertedAsElementImport = new ArrayList<Behavior>() ;
+ classifierInsertedAsElementImport = new ArrayList<Classifier>() ;
+ TypeUtils.predefinedCollectionFunctions = new HashMap<String, SignatureFacade>() ;
+ localInit(library) ;
+ // initializes predefined type facades from TypeUtils
+ TypeUtils._bitString = typeMap.get("BitString") ;
+ TypeUtils._boolean = typeMap.get("Boolean") ;
+ TypeUtils._integer = typeMap.get("Integer") ;
+ TypeUtils._natural = typeMap.get("Natural") ;
+ TypeUtils._string = typeMap.get("String") ;
+ TypeUtils._undefined = new TypeFacade();
+ TypeUtils._unlimited = typeMap.get("UnlimitedNatural") ;
+ TypeUtils._nullExpression = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._undefined) ;
+ TypeUtils._Collection = typeMap.get("Collection") ;
+ TypeUtils._Set = typeMap.get("Set");
+ TypeUtils._Bag = typeMap.get("Bag") ;
+ TypeUtils._Queue = typeMap.get("Queue") ;
+ TypeUtils._OrderedSet = typeMap.get("OrderedSet") ;
+ TypeUtils._List = typeMap.get("List") ;
+ TypeUtils._Deque = typeMap.get("Deque") ;
+ TypeUtils._Map = typeMap.get("Map") ;
+ TypeUtils._Entry = typeMap.get("Entry") ;
+ }
+
+ private void localInit(org.eclipse.uml2.uml.Package library) {
+ if (library.getQualifiedName().equals("Alf::Library::CollectionFunctions")) {
+ this.initCollectionFunctions(library) ;
+ }
+ for (NamedElement n : library.getOwnedMembers()) {
+ if (n instanceof Behavior) {
+ insertSignatureFacade(SignatureFacadeFactory.eInstance.createSignatureFacade(n)) ;
+ }
+ else if (n instanceof Classifier) {
+ insertTypeFacade(TypeFacadeFactory.eInstance.createTypeFacade(n)) ;
+ }
+ else if (n instanceof org.eclipse.uml2.uml.Package) {
+ localInit((org.eclipse.uml2.uml.Package)n) ;
+ }
+ }
+ for (ElementImport eImport : library.getElementImports()) {
+ if (eImport.getImportedElement() instanceof Behavior) {
+ insertSignatureFacade(new SignatureFacade(eImport)) ;
+ behaviorInsertedAsElementImport.add((Behavior)eImport.getImportedElement()) ;
+ }
+ else if (eImport.getImportedElement() instanceof Classifier) {
+ insertTypeFacade(TypeFacadeFactory.eInstance.createTypeFacade(eImport)) ;
+ classifierInsertedAsElementImport.add((Classifier)eImport.getImportedElement()) ;
+ }
+ else if (eImport.getImportedElement() instanceof org.eclipse.uml2.uml.Package) {
+ localInit((org.eclipse.uml2.uml.Package)eImport.getImportedElement()) ;
+ }
+ }
+ for (PackageImport pImport : library.getPackageImports()) {
+ localInit(pImport.getImportedPackage()) ;
+ }
+ TypeUtils._Collection = typeMap.get("Collection") ;
+ TypeUtils._Set = typeMap.get("Set");
+ TypeUtils._Bag = typeMap.get("Bag") ;
+ TypeUtils._Queue = typeMap.get("Queue") ;
+ TypeUtils._OrderedSet = typeMap.get("OrderedSet") ;
+ TypeUtils._List = typeMap.get("List") ;
+ TypeUtils._Deque = typeMap.get("Deque") ;
+ TypeUtils._Map = typeMap.get("Map") ;
+ TypeUtils._Entry = typeMap.get("Entry") ;
+
+ }
+
+ private void initCollectionFunctions(Package library) {
+ for (NamedElement element : library.getOwnedMembers()) {
+ if (element instanceof Behavior) {
+ SignatureFacade s = SignatureFacadeFactory.eInstance.createSignatureFacade(element) ;
+ TypeUtils.predefinedCollectionFunctions.put(s.getName(), s) ;
+ }
+ }
+ for (ElementImport eImport : library.getElementImports()) {
+ if (eImport.getImportedElement() instanceof Behavior) {
+ SignatureFacade s = SignatureFacadeFactory.eInstance.createSignatureFacade(eImport) ;
+ TypeUtils.predefinedCollectionFunctions.put(eImport.getAlias() == null || eImport.getAlias().isEmpty() ? s.getName() : eImport.getAlias(), s) ;
+ }
+ }
+ }
+
+ public List<SignatureFacade> getSignatures(String name) {
+ return behaviorMap.get(name) ;
+ }
+
+ public TypeFacade getClassifier(String name) {
+ return typeMap.get(name) ;
+ }
+
+ private void insertSignatureFacade(SignatureFacade s) {
+ for (Behavior b : behaviorInsertedAsElementImport) {
+ if (s.equals(b))
+ return ;
+ }
+ List<SignatureFacade> l = behaviorMap.get(s.getName()) ;
+ if (l == null) {
+ l = new ArrayList<SignatureFacade>() ;
+ behaviorMap.put(s.getName(), l) ;
+ }
+ l.add(s) ;
+ }
+
+ private void insertTypeFacade(TypeFacade t) {
+ for (Classifier c : classifierInsertedAsElementImport) {
+ if (t.equals(c))
+ return ;
+ }
+ if (typeMap.get(t.getLabel()) == null)
+ typeMap.put(t.getLabel(), t) ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/AssignmentPolicy.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/AssignmentPolicy.java new file mode 100644 index 00000000000..0f950835c5a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/AssignmentPolicy.java @@ -0,0 +1,54 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.AcceptClause;
+import org.eclipse.papyrus.alf.alf.AcceptStatement;
+import org.eclipse.papyrus.alf.alf.InvocationOrAssignementOrDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
+import org.eclipse.uml2.uml.Property;
+
+public class AssignmentPolicy {
+
+ public static AssignmentPolicy eInstance = new AssignmentPolicy() ;
+
+ public String isAssignable(EObject namedElement) {
+ String commonSuffix = " cannot be the target of an assignment" ;
+ if (namedElement instanceof Property) {
+ Property property = (Property)namedElement ;
+ if (property.isReadOnly())
+ return "A read-only property" + commonSuffix ;
+ else
+ return "";
+ }
+ else if (namedElement instanceof LocalNameDeclarationStatement) {
+ return "" ;
+ }
+ else if (namedElement instanceof InvocationOrAssignementOrDeclarationStatement) {
+ return "" ;
+ }
+ else if (namedElement instanceof LoopVariableDefinition) {
+ return "A local loop variable" + commonSuffix ;
+ }
+ else if (namedElement instanceof AcceptClause) {
+ return "A local accept variable" + commonSuffix ;
+ }
+ else if (namedElement instanceof AcceptStatement) {
+ return "A local accept variable" + commonSuffix ;
+ }
+ return "Could not determine if the element is assignable";
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java new file mode 100644 index 00000000000..965ce551f6d --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/DefaultConstructorFacade.java @@ -0,0 +1,74 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Property;
+
+public class DefaultConstructorFacade extends SignatureFacade {
+
+ private Class classToBeConstructed ;
+ private DataType datatypeToBeConstructed ;
+
+ public DefaultConstructorFacade(Class c) {
+ super(c) ;
+ this.classToBeConstructed = c ;
+ this.setReturnType(TypeExpressionFactory.eInstance.createTypeExpression(c)) ;
+ }
+
+ public DefaultConstructorFacade(DataType d) {
+ super(d) ;
+ this.datatypeToBeConstructed = d ;
+ for (Property p : d.getAllAttributes()) {
+ TypeExpression typeOfArgument = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(TypeExpressionFactory.eInstance.createTypeExpression(p)) ;
+ parametersMap.put(p.getName(), typeOfArgument) ;
+ }
+ this.setReturnType(TypeExpressionFactory.eInstance.createTypeExpression(d)) ;
+ }
+
+ @Override
+ public String getName() {
+ return classToBeConstructed.getName();
+ }
+
+ @Override
+ public boolean hasReturnType() {
+ return true;
+ }
+
+ @Override
+ public String getLabel() {
+ String label = classToBeConstructed != null ? classToBeConstructed.getName() : datatypeToBeConstructed.getName() ;
+ label += "(" ;
+ boolean first = true ;
+ for (TypeExpression t : parameters) {
+ if (first) first = false ; else label += ", " ;
+ label += t.getLabel() ;
+ }
+ label += ") : " + this.getReturnType().getLabel() ;
+ return label ;
+ }
+
+ @Override
+ public boolean isAConstructor() {
+ return true;
+ }
+
+ @Override
+ public boolean isADestructor(){
+ return false ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/DefaultDestructorFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/DefaultDestructorFacade.java new file mode 100644 index 00000000000..b9be485e640 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/DefaultDestructorFacade.java @@ -0,0 +1,34 @@ +package org.eclipse.papyrus.alf.validation.typing;
+
+public class DefaultDestructorFacade extends SignatureFacade {
+
+ public DefaultDestructorFacade() {
+ super() ;
+ }
+
+ @Override
+ public String getName() {
+ return "destroy";
+ }
+
+ @Override
+ public boolean hasReturnType() {
+ return true;
+ }
+
+ @Override
+ public String getLabel() {
+ return "destroy()" ;
+ }
+
+ @Override
+ public boolean isAConstructor() {
+ return false;
+ }
+
+ @Override
+ public boolean isADestructor(){
+ return true ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/ErrorTypeFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/ErrorTypeFacade.java new file mode 100644 index 00000000000..2ae720aea18 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/ErrorTypeFacade.java @@ -0,0 +1,50 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class ErrorTypeFacade extends TypeFacade {
+
+ private String errorMessage = "" ;
+ private EStructuralFeature structuralFeature ;
+ private EObject errorSource ;
+
+ @Override
+ public String getLabel() {
+ return errorMessage ;
+ }
+
+ public void setMessage(String message) {
+ errorMessage = "" + message ;
+ }
+
+ public EStructuralFeature getStructuralFeature() {
+ return structuralFeature;
+ }
+
+ public void setStructuralFeature(EStructuralFeature structuralFeature) {
+ this.structuralFeature = structuralFeature ;
+ }
+
+ public EObject getErrorSource() {
+ return errorSource;
+ }
+
+ public void setErrorSource(EObject errorSource) {
+ this.errorSource = errorSource ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java new file mode 100644 index 00000000000..4ab7b6363c4 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacade.java @@ -0,0 +1,105 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+public class MultiplicityFacade {
+ private int lowerBound = 0;
+ private int upperBound = 0;
+ private boolean nonUnique = false ;
+ private boolean ordered = false ;
+
+ public String getLabel() {
+ if (lowerBound == upperBound) {
+ if (lowerBound == 1)
+ return "" ;
+ if (lowerBound == -1)
+ return "[*]" ;
+ return "[" + lowerBound + "]" ;
+ }
+ else {
+ if (upperBound == -1) {
+ if (lowerBound == 0) {
+ return "[*]" ;
+ }
+ else {
+ return "[" + lowerBound + "..*]" ;
+ }
+ }
+ else {
+ return "[" + lowerBound + ".." + upperBound + "]";
+ }
+ }
+ }
+
+ public boolean isCompatibleWithMe(MultiplicityFacade multiplicity) {
+ //boolean lowerBoundCompatible = multiplicity.lowerBound >= this.lowerBound ;
+ boolean upperBoundCompatible = true ;
+
+ switch (this.upperBound) {
+ case -1:
+ break;
+
+ default:
+ if (multiplicity.upperBound == -1)
+ upperBoundCompatible = false ;
+// else
+// upperBoundCompatible = multiplicity.upperBound <= this.upperBound ;
+ break;
+ }
+
+ //return lowerBoundCompatible && upperBoundCompatible;
+ return upperBoundCompatible ;
+ }
+
+ public void setLowerBound(int lowerBound) {
+ this.lowerBound = lowerBound ;
+ }
+
+ public void setUpperBound(int lowerBound) {
+ this.upperBound = lowerBound ;
+ }
+
+ public int getLowerBound() {
+ return lowerBound;
+ }
+
+ public int getUpperBound() {
+ return upperBound;
+ }
+
+ public boolean isUnique() {
+ return !nonUnique ;
+ }
+
+ public boolean isOrdered() {
+ return ordered ;
+ }
+
+ public boolean isSequence() {
+ return ordered && nonUnique ;
+ }
+
+ public void setIsUnique(boolean isUnique) {
+ nonUnique = !isUnique ;
+ }
+
+ public void setIsOrdered(boolean isOrdered) {
+ ordered = isOrdered ;
+ }
+
+ public void setIsSequence(boolean isSequence) {
+ ordered = true ;
+ nonUnique = true ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacadeFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacadeFactory.java new file mode 100644 index 00000000000..d300085f056 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/MultiplicityFacadeFactory.java @@ -0,0 +1,65 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
+import org.eclipse.uml2.uml.MultiplicityElement;
+
+public class MultiplicityFacadeFactory {
+
+ public static MultiplicityFacadeFactory eInstance = new MultiplicityFacadeFactory() ;
+
+ public MultiplicityFacade createMultiplicityFacade(int lowerBound, int upperBound, boolean isUnique, boolean isOrdered) {
+ MultiplicityFacade result = new MultiplicityFacade() ;
+ result.setLowerBound(lowerBound) ;
+ result.setUpperBound(upperBound) ;
+ result.setIsUnique(isUnique) ;
+ result.setIsOrdered(isOrdered) ;
+ return result ;
+ }
+
+ public MultiplicityFacade createMultiplicityFacade(int upperBound) {
+ if (upperBound == -1)
+ return createMultiplicityFacade(0, upperBound, false, true) ;
+ else
+ return createMultiplicityFacade(upperBound, upperBound, true, false) ;
+ }
+
+ public MultiplicityFacade createMultiplicityFacade() {
+ return createMultiplicityFacade(1, 1, true, false) ;
+ }
+
+ public MultiplicityFacade createMultiplicityFacade(EObject multiplicityElement) {
+ // To be overriden
+ if (multiplicityElement instanceof MultiplicityElement) {
+ MultiplicityElement m = (MultiplicityElement)multiplicityElement ;
+ return createMultiplicityFacade(m.getLower(), m.getUpper(), m.isUnique(), m.isOrdered()) ;
+ }
+ else if (multiplicityElement instanceof LocalNameDeclarationStatement) {
+ LocalNameDeclarationStatement statement = (LocalNameDeclarationStatement)multiplicityElement ;
+ int lower = statement.isMultiplicityIndicator() ? 0 : 1 ;
+ int upper = statement.isMultiplicityIndicator() ? -1 : 1 ;
+ boolean isUnique = statement.isMultiplicityIndicator() ? false : true ;
+ boolean isOrdered = statement.isMultiplicityIndicator() ? true : false ;
+ return createMultiplicityFacade(lower, upper, isUnique, isOrdered) ;
+ }
+ else if (multiplicityElement instanceof LoopVariableDefinition) {
+ // Correctly handled by the following return statement
+ }
+ return createMultiplicityFacade() ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/OperationFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/OperationFacade.java new file mode 100644 index 00000000000..7ad3c700a33 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/OperationFacade.java @@ -0,0 +1,18 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+public class OperationFacade {
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/PropertyFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/PropertyFacade.java new file mode 100644 index 00000000000..bb152c23f22 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/PropertyFacade.java @@ -0,0 +1,18 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+public class PropertyFacade {
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java new file mode 100644 index 00000000000..02d05be58d6 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacade.java @@ -0,0 +1,301 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Reception;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateableElement;
+
+public class SignatureFacade {
+
+ private String name = "";
+ protected List<TypeExpression> parameters = new ArrayList<TypeExpression>();
+ //
+ protected Map<String, TypeExpression> parametersMap = new HashMap<String, TypeExpression>() ;
+ //
+ //private TypeExpression returnType = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._undefined, 0, 0, false, false) ;
+ private TypeExpression returnType = null ;
+ private EObject actualSignatureObject = null ;
+
+ public EObject getActualSignatureObject() {
+ return actualSignatureObject;
+ }
+
+ public SignatureFacade() {
+
+ }
+
+ public SignatureFacade(EObject o) {
+ if (o instanceof Operation) {
+ Operation operation = (Operation)o ;
+ this.actualSignatureObject = operation ;
+ this.name = operation.getName() ;
+ for (Parameter p : operation.getOwnedParameters()) {
+ if (p.getDirection() == ParameterDirectionKind.RETURN_LITERAL)
+ returnType = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ else {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
+ }
+ }
+ else if (o instanceof Behavior) {
+ Behavior behavior = (Behavior) o ;
+ this.actualSignatureObject = behavior ;
+ this.name = behavior.getName() ;
+ for (Parameter p : behavior.getOwnedParameters()) {
+ if (p.getDirection() == ParameterDirectionKind.RETURN_LITERAL)
+ returnType = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ else {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
+ }
+ }
+ else if (o instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)o ;
+ if (eImport.getImportedElement() instanceof Behavior) {
+ Behavior b = (Behavior)eImport.getImportedElement() ;
+ this.actualSignatureObject = b ;
+ if (eImport.getAlias() != null)
+ this.name = eImport.getAlias() ;
+ else
+ this.name = b.getName() ;
+ for (Parameter p : b.getOwnedParameters()) {
+ if (p.getDirection() == ParameterDirectionKind.RETURN_LITERAL)
+ returnType = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ else {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
+ }
+ }
+ }
+ else if (o instanceof Reception) {
+ Reception r = (Reception)o ;
+ this.actualSignatureObject = r ;
+ this.name = r.getName() ;
+ if (r.getSignal() != null) {
+ for (Property p : r.getSignal().getAllAttributes()) {
+ TypeExpression typeOfP = TypeExpressionFactory.eInstance.createTypeExpression(p) ;
+ parameters.add(typeOfP) ;
+ parametersMap.put(p.getName(), typeOfP) ;
+ }
+ }
+ }
+ }
+
+ public String getName() {
+ return name ;
+ }
+
+ public void setName(String name) {
+ this.name = "" + name ;
+ }
+
+ public List<TypeExpression> getParameters() {
+ return parameters ;
+ }
+
+ public boolean hasReturnType() {
+ return returnType != null ;
+ }
+
+ public TypeExpression getReturnType() {
+ return returnType ;
+ }
+
+ public void setReturnType(TypeExpression returnType) {
+ this.returnType = returnType ;
+ }
+
+ public String isCompatibleWithMe(List<TypeExpression> arguments, boolean getErrorMessage) {
+ int compatibilityLevel = this.isCompatibleWithMe(arguments) ;
+ String errorMessage = "" ;
+ if (compatibilityLevel == 0) {
+ errorMessage += this.getLabel() + " does not apply to arguments " ;
+ String argumentsString = "(" ;
+ boolean first = true ;
+ for (TypeExpression type : arguments) {
+ if (!first) argumentsString += ", " ; else first = false ;
+ argumentsString += type.getLabel() ;
+ }
+ argumentsString += ")" ;
+ errorMessage += argumentsString ;
+ }
+ return errorMessage ;
+ }
+
+ public String getLabel() {
+ String label = name + "(" ;
+ boolean first = true ;
+ for (TypeExpression type : parameters) {
+ if (!first) label += ", " ; else first = false ;
+ label += type.getLabel() ;
+ }
+ label += ")" ;
+ return label ;
+ }
+
+ public int isCompatibleWithMe(List<TypeExpression> arguments) {
+ if (arguments.size() != parameters.size())
+ return 0 ;
+ else if (arguments.size() == 0 )
+ return 3 ;
+ int compatibilityLevel = 0 ;
+ boolean first = true ;
+ for (int i = 0 ; i < parameters.size() ; i++) {
+ int currentCompatibilityLevel = parameters.get(i).isCompatibleWithMe(arguments.get(i)) ;
+ if (first && currentCompatibilityLevel < 3)
+ return 0 ; //TODO: temporary solution. this is to give a higher value to the first argument if it perfectly matches. Should probably consider the context... Check the spec...
+ if (currentCompatibilityLevel == 0)
+ return 0 ;
+ else {
+ compatibilityLevel += currentCompatibilityLevel ;
+ }
+ first = false ;
+ }
+ return compatibilityLevel ;
+ }
+
+ public String isCompatibleWithMe(Map<String,TypeExpression> arguments) {
+ if (arguments.keySet().size() == 0 )
+ return "" ;
+ String compatibility = "" ;
+ for (String parameterName : arguments.keySet()) {
+ if (parametersMap.get(parameterName) == null) {
+ compatibility += "Parameter " + parameterName + " is undefined\n";
+ }
+ else {
+ int compatibilityLevel = parametersMap.get(parameterName).isCompatibleWithMe(arguments.get(parameterName)) ;
+ if (compatibilityLevel == 0) {
+ compatibility += "Parameter " + parameterName + " requires an argument of type " + parametersMap.get(parameterName).getLabel() + "\n" ;
+ }
+ }
+ }
+ return compatibility ;
+ }
+
+ public static List<SignatureFacade> findNearestSignature(List<TypeExpression> arguments, List<SignatureFacade> candidates) {
+ List<SignatureFacade> matchingSignatures = new ArrayList<SignatureFacade>() ;
+ int bestScore = 0 ;
+ for (SignatureFacade cddMatchingSignature : candidates) {
+ int currentScore = cddMatchingSignature.isCompatibleWithMe(arguments) ;
+ if (currentScore != 0) {
+ if (currentScore >= bestScore) {
+ if (currentScore > bestScore)
+ matchingSignatures.clear() ;
+ matchingSignatures.add(cddMatchingSignature) ;
+ bestScore = currentScore ;
+ }
+ }
+ }
+ return matchingSignatures ;
+ }
+
+ public static List<SignatureFacade> findNearestConstructorSignature(Map<String, TypeExpression> arguments, List<SignatureFacade> candidates) {
+ List<SignatureFacade> matchingSignatures = new ArrayList<SignatureFacade>() ;
+ for (SignatureFacade cddMatchingSignature : candidates) {
+ String compatibility = cddMatchingSignature.isCompatibleWithMe(arguments) ;
+ if (compatibility.isEmpty()) {
+ matchingSignatures.add(cddMatchingSignature) ;
+ }
+ }
+ return matchingSignatures ;
+ }
+
+ public List<SignatureFacade> isNotDistinguishableFrom(List<SignatureFacade> candidates) {
+ List<SignatureFacade> matchingSignatures = new ArrayList<SignatureFacade>() ;
+ for (SignatureFacade cddMatchingSignature : candidates) {
+ if (this.name.equals(cddMatchingSignature.getName())) {
+ if (this.parameters.size() == cddMatchingSignature.parameters.size()) {
+ boolean parameterThatDoesNotMatchFound = false ;
+ for (int i = 0 ; i < this.parameters.size() && !parameterThatDoesNotMatchFound ; ) {
+ int compatibilityLevel = this.parameters.get(i).isCompatibleWithMe(cddMatchingSignature.getParameters().get(i)) ;
+ if (compatibilityLevel != 3)
+ parameterThatDoesNotMatchFound = true ;
+ i++ ;
+ }
+ if (!parameterThatDoesNotMatchFound) {
+ matchingSignatures.add(cddMatchingSignature) ;
+ }
+ }
+ }
+ }
+ return matchingSignatures ;
+ }
+
+ public boolean equals(Operation o) {
+ return this.actualSignatureObject == o ;
+ }
+
+ public boolean equals(Behavior b) {
+ return this.actualSignatureObject == b ;
+ }
+
+ public boolean isAConstructor() {
+ Element signature = null ;
+ if (actualSignatureObject instanceof Operation || actualSignatureObject instanceof Behavior)
+ signature = (Element)actualSignatureObject ;
+ else if (actualSignatureObject instanceof ElementImport)
+ signature = (Element)((ElementImport)actualSignatureObject).getImportedElement() ;
+ if (signature == null)
+ return false ;
+ return signature.getAppliedStereotype("Standard::Create") != null ;
+ }
+
+ public boolean isADestructor() {
+ Element signature = null ;
+ if (actualSignatureObject instanceof Operation || actualSignatureObject instanceof Behavior)
+ signature = (Element)actualSignatureObject ;
+ else if (actualSignatureObject instanceof ElementImport)
+ signature = (Element)((ElementImport)actualSignatureObject).getImportedElement() ;
+ if (signature == null)
+ return false ;
+ return signature.getAppliedStereotype("Standard::Destroy") != null ;
+ }
+
+ public Map<String, TypeExpression> getParametersMap() {
+ return this.parametersMap ;
+ }
+
+ public boolean isATemplate() {
+ if (this.actualSignatureObject instanceof TemplateableElement) {
+ return ((TemplateableElement)this.actualSignatureObject).isTemplate() ;
+ }
+ return false ;
+ }
+
+ public SignatureFacade bindTemplate(Map<TemplateParameter, ParameterableElement> substitutions) {
+ // Templates are not supported in this version of the editor
+ return this ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java new file mode 100644 index 00000000000..6f8377b0fe6 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/SignatureFacadeFactory.java @@ -0,0 +1,286 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.InstanceCreationExpression;
+import org.eclipse.papyrus.alf.alf.InstanceCreationTupleElement;
+import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding;
+import org.eclipse.papyrus.alf.scoping.AlfScopeProvider;
+import org.eclipse.uml2.uml.Class;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.DataType;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.PrimitiveType;
+
+public class SignatureFacadeFactory {
+
+ public static SignatureFacadeFactory eInstance = new SignatureFacadeFactory() ;
+
+ public SignatureFacade createSignatureFacade(EObject o) {
+ return new SignatureFacade(o) ;
+ }
+
+ public SignatureFacade createConstructorFacade(InstanceCreationExpression exp) throws Exception {
+ List<TypeExpression> arguments = new ArrayList<TypeExpression>() ;
+ Map<String, TypeExpression> argumentsMap = new HashMap<String, TypeExpression>() ;
+
+ if (exp.getTuple().getInstanceCreationTupleElement() != null) {
+ for (InstanceCreationTupleElement tupleElement : exp.getTuple().getInstanceCreationTupleElement()) {
+ TypeExpression typeOfArgument = new TypeUtils().getTypeOfExpression(tupleElement.getObject()) ;
+ if (typeOfArgument.getTypeFacade() instanceof ErrorTypeFacade)
+ throw new TypeInferenceException(typeOfArgument) ;
+ arguments.add(typeOfArgument) ;
+ argumentsMap.put(tupleElement.getRole(), typeOfArgument) ;
+ }
+ }
+
+ // first try to determine if the expression directly refers to a Class or a DataType
+ TypeFacade cddClassifier = TypeFacadeFactory.eInstance.createVoidFacade(exp.getConstructor()) ;
+ boolean errorInResolutionOfClassifier = false ;
+ if (cddClassifier instanceof ErrorTypeFacade) {
+ errorInResolutionOfClassifier = true ;
+ }
+ else {
+ Classifier referencedType = cddClassifier.extractActualType() ;
+ if (referencedType instanceof PrimitiveType) {
+ throw new Exception("Constructor invocations do not apply to primitive types") ;
+ }
+ if (referencedType instanceof Enumeration) {
+ throw new Exception("Constructor invocations do not apply to enumerations") ;
+ }
+ if (referencedType.isAbstract()) {
+ throw new Exception("Abstract classifiers cannot be instantiated") ;
+ }
+
+ // The classifier has been resolved. Must determine if arguments match with possible constructors
+ if (referencedType instanceof org.eclipse.uml2.uml.Class) {
+ List<EObject> visibleConstructor = AlfScopeProvider.scopingTool.getVisibleOperationsOrBehaviors(referencedType).resolveByName(referencedType.getName()) ;
+ if (visibleConstructor.size() > 1) {
+ // try to match with arguments
+ // if does not match, raise an exception
+ List<SignatureFacade> visibleConstructorSignatures = new ArrayList<SignatureFacade>() ;
+ for (EObject cddConstructor : visibleConstructor) {
+ SignatureFacade cddConstructorSignature = SignatureFacadeFactory.eInstance.createSignatureFacade(cddConstructor) ;
+ if (cddConstructorSignature.isAConstructor())
+ visibleConstructorSignatures.add(cddConstructorSignature) ;
+ }
+ List<SignatureFacade> matchingSignatures = SignatureFacade.findNearestSignature(arguments, visibleConstructorSignatures) ;
+ if (matchingSignatures.size() > 1) {
+ String errorMessage = referencedType.getName() + "(" ;
+ boolean first = true ;
+ for (TypeExpression arg : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += arg.getLabel() ;
+ }
+ errorMessage += ") resolves to multiple constructors" ;
+ throw new Exception(errorMessage) ;
+ }
+ else if (matchingSignatures.size() == 0) {
+ String errorMessage = "Constructor " + referencedType.getName() + "(" ;
+ boolean first = true ;
+ for (TypeExpression arg : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += arg.getLabel() ;
+ }
+ errorMessage += ") is undefined" ;
+ throw new Exception(errorMessage) ;
+ }
+ else { // exactly one match
+ return matchingSignatures.get(0) ;
+ }
+ }
+ else if (visibleConstructor.size() == 0) {
+ if (arguments.size() > 0) {
+ // Throw an exception
+ String errorMessage = "Constructor " + referencedType.getName() + "(";
+ boolean first = true ;
+ for (TypeExpression t : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += t.getLabel() ;
+ }
+ errorMessage += ") is undefined" ;
+ throw new Exception(errorMessage) ;
+ }
+ return new DefaultConstructorFacade((Class)referencedType) ;
+ }
+ else { // exactly one constructor found
+ // Tries to determine if arguments match
+ SignatureFacade constructor = createSignatureFacade(visibleConstructor.get(0)) ;
+ if (!constructor.isAConstructor()) {
+ // Throw an exception
+ String errorMessage = "Constructor " + referencedType.getName() + "(";
+ boolean first = true ;
+ for (TypeExpression t : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += t.getLabel() ;
+ }
+ errorMessage += ") is undefined" ;
+ throw new Exception(errorMessage) ;
+ }
+ String potentialErrorMessage = constructor.isCompatibleWithMe(argumentsMap) ;
+ if (potentialErrorMessage.length() == 0)
+ return constructor ;
+ else
+ throw new Exception(potentialErrorMessage) ;
+ }
+ }
+ else if (referencedType instanceof DataType){ // This is a data type.
+ //must match arguments with visible properties of the data type
+ SignatureFacade defaultDataTypeConstructor = new DefaultConstructorFacade((DataType)referencedType) ;
+ String errorMessage = defaultDataTypeConstructor.isCompatibleWithMe(argumentsMap) ;
+ if (!(errorMessage.length() == 0))
+ throw new Exception(errorMessage) ;
+ else
+ return defaultDataTypeConstructor ;
+ }
+ }
+
+ if (errorInResolutionOfClassifier) {
+ // We can try again, but considering that:
+ // - the last element in the qualified name as the name of a constructor
+ // - the element before the last element is a class name
+
+ if (exp.getConstructor().getRemaining() == null)
+ throw new Exception("Constructor " + exp.getConstructor().getId() + " is undefined") ;
+
+ QualifiedNameWithBinding remaining = exp.getConstructor() ;
+ QualifiedNameWithBinding cddClassName = exp.getConstructor() ;
+ QualifiedNameWithBinding cddConstructorName = exp.getConstructor() ;
+ EObject previousPackage = null ;
+
+ while (cddConstructorName.getRemaining() != null) {
+ cddClassName = cddConstructorName ;
+ cddConstructorName = cddConstructorName.getRemaining() ;
+ }
+
+ if (remaining != cddClassName) {
+ List<EObject> visiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(exp).resolveByName(remaining.getId()) ;
+ if (visiblePackages.isEmpty()) {
+ throw new Exception("Could not resolve package " + remaining.getId()) ;
+ }
+ else if (visiblePackages.size() > 1) {
+ throw new Exception(remaining.getId() + " resolves to multiple packages") ;
+ }
+ else {
+ List<EObject> nestedVisiblePackages ;
+ previousPackage = visiblePackages.get(0) ;
+ remaining = remaining.getRemaining() ;
+ while (remaining != cddClassName) {
+ nestedVisiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(previousPackage).resolveByName(remaining.getId()) ;
+ if (nestedVisiblePackages.isEmpty()) {
+ throw new Exception("Could not resolve package " + remaining.getId()) ;
+ }
+ else if (nestedVisiblePackages.size() > 1) {
+ throw new Exception(remaining.getId() + " resolves to multiple packages") ;
+ }
+ previousPackage = nestedVisiblePackages.get(0) ;
+ remaining = remaining.getRemaining() ;
+ }
+ }
+ }
+
+
+ // At this point, the (potential) path has been validated
+ // cddClassName should resolve to a classifier
+ List<EObject> visibleClassifiers = null ;
+ EObject resolvedClassifier = null ;
+ if (previousPackage != null)
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousPackage).resolveByName(cddClassName.getId()) ;
+ else
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(cddClassName.getId()) ;
+ if (visibleClassifiers.isEmpty()) {
+ throw new Exception("Could not resolve classifier " + cddClassName.getId()) ;
+ }
+ else if (visibleClassifiers.size() > 1) {
+ throw new Exception(remaining.getId() + " resolves to multiple classifiers.") ;
+ }
+ else {
+ resolvedClassifier = visibleClassifiers.get(0) ;
+ }
+ List<EObject> visibleConstructor = AlfScopeProvider.scopingTool.getVisibleOperationsOrBehaviors(resolvedClassifier).resolveByName(cddConstructorName.getId()) ;
+ if (visibleConstructor.size() > 1) {
+ // try to match with arguments
+ // if does not match, raise an exception
+ List<SignatureFacade> visibleConstructorSignatures = new ArrayList<SignatureFacade>() ;
+ for (EObject cddConstructor : visibleConstructor) {
+ SignatureFacade cddConstructorSignature = SignatureFacadeFactory.eInstance.createSignatureFacade(cddConstructor) ;
+ if (cddConstructorSignature.isAConstructor())
+ visibleConstructorSignatures.add(cddConstructorSignature) ;
+ }
+ List<SignatureFacade> matchingSignatures = SignatureFacade.findNearestSignature(arguments, visibleConstructorSignatures) ;
+ if (matchingSignatures.size() > 1) {
+ String errorMessage = cddConstructorName.getId() + "(" ;
+ boolean first = true ;
+ for (TypeExpression arg : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += arg.getLabel() ;
+ }
+ errorMessage += ") resolves to multiple constructors" ;
+ throw new Exception(errorMessage) ;
+ }
+ else if (matchingSignatures.size() == 0) {
+ String errorMessage = "Constructor " + cddConstructorName.getId() + "(" ;
+ boolean first = true ;
+ for (TypeExpression arg : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += arg.getLabel() ;
+ }
+ errorMessage += ") is undefined" ;
+ throw new Exception(errorMessage) ;
+ }
+ else { // exactly one match
+ return matchingSignatures.get(0) ;
+ }
+ }
+ else if (visibleConstructor.size() == 0) {
+ String errorMessage = "Constructor " + cddConstructorName.getId() + "(" ;
+ boolean first = true ;
+ for (TypeExpression arg : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += arg.getLabel() ;
+ }
+ errorMessage += ") is undefined" ;
+ throw new Exception(errorMessage) ;
+ }
+ else { // exactly one constructor
+ // Tries to determine if arguments match
+ SignatureFacade constructor = createSignatureFacade(visibleConstructor.get(0)) ;
+ if (!constructor.isAConstructor()) {
+ // Throw an exception
+ String errorMessage = "Constructor " + cddConstructorName.getId() + "(";
+ boolean first = true ;
+ for (TypeExpression t : arguments) {
+ if (first) first = false ; else errorMessage += ", " ;
+ errorMessage += t.getLabel() ;
+ }
+ errorMessage += ") is undefined" ;
+ throw new Exception(errorMessage) ;
+ }
+ String potentialErrorMessage = constructor.isCompatibleWithMe(arguments, true) ;
+ if (potentialErrorMessage.length() == 0)
+ return constructor ;
+ else
+ throw new Exception(potentialErrorMessage) ;
+ }
+ }
+
+ throw new Exception("Not supported case") ;
+ }
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeExpression.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeExpression.java new file mode 100644 index 00000000000..281fab4fd91 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeExpression.java @@ -0,0 +1,74 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+public class TypeExpression {
+
+ private TypeFacade type ;
+ private MultiplicityFacade multiplicity ;
+
+ public String getLabel() {
+ String label = "" ;
+ label += type.getLabel() ;
+ label += multiplicity.getLabel() ;
+ return label ;
+ }
+
+ public TypeFacade getTypeFacade() {
+ return type ;
+ }
+
+ public MultiplicityFacade getMultiplicityFacade() {
+ return multiplicity ;
+ }
+
+ public int isCompatibleWithMe(TypeExpression t) {
+ if (t == TypeUtils._nullExpression)
+ return 3 ;
+ int typeCompatibilityLevel = type.isCompatibleWithMe(t.type) ;
+ if (typeCompatibilityLevel == 0)
+ return 0 ;
+ boolean isCompatible = multiplicity.isCompatibleWithMe(t.multiplicity) ;
+ if (isCompatible)
+ return typeCompatibilityLevel ;
+ else
+ return 0 ;
+ }
+
+ public void setType(TypeFacade type) {
+ this.type = type;
+ }
+
+ public MultiplicityFacade getMultiplicity() {
+ return multiplicity;
+ }
+
+ public void setMultiplicity(MultiplicityFacade multiplicity) {
+ this.multiplicity = multiplicity;
+ }
+
+ public boolean isACollection() {
+ boolean isACollection =
+ this.multiplicity.getUpperBound() == -1 || this.multiplicity.getUpperBound() > 1 ||
+ this.type.isACollection();
+
+ return isACollection ;
+ }
+
+ public boolean isOrdered() {
+ return this.multiplicity.isOrdered() || this.type.isOrdered() ;
+ // To be completed with collection classes
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeExpressionFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeExpressionFactory.java new file mode 100644 index 00000000000..d004049eab2 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeExpressionFactory.java @@ -0,0 +1,43 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.emf.ecore.EObject;
+
+public class TypeExpressionFactory {
+
+ public static TypeExpressionFactory eInstance = new TypeExpressionFactory() ;
+
+ public TypeExpression createTypeExpression(EObject typeExpressionSource) {
+ TypeExpression result = new TypeExpression() ;
+ result.setType(TypeFacadeFactory.eInstance.createTypeFacade(typeExpressionSource)) ;
+ result.setMultiplicity(MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(typeExpressionSource)) ;
+ return result ;
+ }
+
+ public TypeExpression createTypeExpression(TypeFacade type) {
+ TypeExpression result = new TypeExpression() ;
+ result.setType(type) ;
+ result.setMultiplicity (MultiplicityFacadeFactory.eInstance.createMultiplicityFacade()) ;
+ return result ;
+ }
+
+ public TypeExpression createTypeExpression(TypeFacade type, int lowerBound, int upperBound, boolean isUnique, boolean isOrdered) {
+ TypeExpression result = new TypeExpression() ;
+ result.setType(type) ;
+ result.setMultiplicity (MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(lowerBound, upperBound, isUnique, isOrdered)) ;
+ return result ;
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java new file mode 100644 index 00000000000..770cb144623 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeFacade.java @@ -0,0 +1,178 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.alf.alf.Expression;
+import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
+import org.eclipse.papyrus.alf.alf.SuffixExpression;
+import org.eclipse.papyrus.alf.validation.AlfJavaValidator;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TypedElement;
+
+public class TypeFacade {
+
+ protected EObject typeObject ;
+
+ public void setTypeObject(EObject typeObject) {
+ this.typeObject = typeObject ;
+ //TODO this.templateBindingFacade = TemplateBindingFacadeFactory.eInstance.createTemplateBindingFacade(typeObject) ;
+ }
+
+ public String getLabelWithoutBinding() {
+ if (typeObject == null)
+ return "<Undefined>" ;
+ return "" ;
+ }
+
+ public int isCompatibleWithMe(TypeFacade type) {
+ Classifier myType = extractActualType(this) ;
+ if (myType == null) // i.e. any
+ return 3 ;
+ Classifier hisType = extractActualType(type) ;
+ if (hisType == null)
+ return 0 ;
+ if (perfectMatch(myType, hisType))
+ return 3 ;
+ //else if (autoConversionMatch(myType, hisType)) TODO: temporarily commented. Rules need to be clarified
+ // return 2 ;
+ else if (inheritanceMatch(myType, hisType))
+ return 1 ;
+ else
+ return 0 ;
+ }
+
+ private boolean perfectMatch(Classifier myType, Classifier hisType) {
+ boolean myTypeIsPredefined =
+ myType.getName().equals("Integer") ||
+ myType.getName().equals("String") ||
+ myType.getName().equals("Boolean") ||
+ myType.getName().equals("UnlimitedNatural");
+ boolean hisTypeIsPredefined =
+ hisType.getName().equals("Integer") ||
+ hisType.getName().equals("String") ||
+ hisType.getName().equals("Boolean") ||
+ hisType.getName().equals("UnlimitedNatural");
+
+ if (myTypeIsPredefined && hisTypeIsPredefined)
+ return myType.getName().equals(hisType.getName()) ;
+
+ return myType == hisType ;
+ }
+
+ private boolean autoConversionMatch(Classifier myType, Classifier hisType) {
+ String autoConvertionOperatorName = "To" + myType.getName() ;
+ List<SignatureFacade> availableConversionOperator =
+ AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(autoConvertionOperatorName) ;
+ if (availableConversionOperator.isEmpty())
+ return false ;
+ else {
+ int numberOfMatchingOperators = 0 ;
+ for (SignatureFacade cddMatchingConvertionOperator : availableConversionOperator) {
+ Classifier parameterType = extractActualType(cddMatchingConvertionOperator.getParameters().get(0).getTypeFacade()) ;
+ Classifier returnType = extractActualType(cddMatchingConvertionOperator.getReturnType().getTypeFacade()) ;
+ if (perfectMatch(parameterType, hisType) && perfectMatch(returnType, myType))
+ numberOfMatchingOperators++ ;
+ }
+ return numberOfMatchingOperators == 1 ;
+ }
+ }
+
+ private boolean inheritanceMatch(Classifier myType, Classifier hisType) {
+ return hisType.getGenerals().contains(myType) ;
+ }
+
+ public static Classifier extractActualType(TypeFacade t) {
+ Classifier actualType = null ;
+ if (t.typeObject instanceof Classifier)
+ actualType = (Classifier)t.typeObject ;
+ else if (t.typeObject instanceof ElementImport){
+ ElementImport eImport = (ElementImport)t.typeObject ;
+ if (eImport.getImportedElement() instanceof Classifier)
+ actualType = (Classifier)eImport.getImportedElement() ;
+ }
+ else if (t.typeObject instanceof TypedElement) {
+ actualType = (Classifier)((TypedElement)t.typeObject).getType() ;
+ }
+ else if (t instanceof VoidFacade) {
+ actualType = extractActualType(((VoidFacade)t).getTypeFacade()) ;
+ }
+ else if (t.typeObject instanceof SequenceExpansionExpression) {
+ // first retrieves the expression nesting this sequence variable
+ EObject cddExpression = t.typeObject.eContainer() ;
+ while (! (cddExpression instanceof Expression))
+ cddExpression = cddExpression.eContainer() ;
+ // infers the type of the nesting expression, ignoring the t.typeObject suffix
+ TypeExpression typeOfPrefix = new TypeUtils((SuffixExpression)t.typeObject).getTypeOfExpression((Expression)cddExpression) ;
+ actualType = extractActualType(typeOfPrefix.getTypeFacade()) ;
+ for (Operation o : actualType.getAllOperations()) {
+ if (o.getName().equals("toSequence")) {
+ actualType = (Classifier) (o.getReturnResult() != null ? o.getReturnResult().getType() : actualType) ;
+ }
+ }
+ }
+ return actualType ;
+ }
+
+ public Classifier extractActualType() {
+ return extractActualType(this) ;
+ }
+
+ public boolean isAbstract() {
+ Classifier myType = extractActualType() ;
+ return myType != null ? myType.isAbstract() : false ;
+ }
+
+ public boolean isATemplate() {
+ Classifier myType = extractActualType() ;
+ return myType != null ? myType.isTemplate() : false ;
+ }
+
+ public boolean equals(Classifier c) {
+ return this.typeObject == c ;
+ }
+
+ public boolean isACollection() {
+ return
+ this.isCompatibleWithMe(TypeUtils._Collection) > 0
+ || this.isCompatibleWithMe(TypeUtils._Set) > 0
+ || this.isCompatibleWithMe(TypeUtils._Bag) > 0
+ || this.isCompatibleWithMe(TypeUtils._Queue) > 0
+ || this.isCompatibleWithMe(TypeUtils._OrderedSet) > 0
+ || this.isCompatibleWithMe(TypeUtils._List) > 0
+ || this.isCompatibleWithMe(TypeUtils._Deque) > 0
+ || this.isCompatibleWithMe(TypeUtils._Map) > 0 ;
+ }
+
+ public boolean isOrdered() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public String getLabel() {
+ return "" ; // TODO: uncomment when template bindings are supported + this.templateBindingFacade.getLabel() ;
+ }
+
+ public void bindTemplate(Map<TemplateParameter, ParameterableElement> substitutions) {
+ // Templates are not supported in this version of the alf editor
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java new file mode 100644 index 00000000000..f9f42e2beb8 --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeFacadeFactory.java @@ -0,0 +1,393 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.papyrus.alf.alf.AcceptClause;
+import org.eclipse.papyrus.alf.alf.AcceptStatement;
+import org.eclipse.papyrus.alf.alf.AlfPackage;
+import org.eclipse.papyrus.alf.alf.ClassificationExpression;
+import org.eclipse.papyrus.alf.alf.Expression;
+import org.eclipse.papyrus.alf.alf.InvocationOrAssignementOrDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LocalNameDeclarationStatement;
+import org.eclipse.papyrus.alf.alf.LoopVariableDefinition;
+import org.eclipse.papyrus.alf.alf.NameExpression;
+import org.eclipse.papyrus.alf.alf.NamedTemplateBinding;
+import org.eclipse.papyrus.alf.alf.QualifiedNameWithBinding;
+import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
+import org.eclipse.papyrus.alf.alf.SuperInvocationExpression;
+import org.eclipse.papyrus.alf.alf.UnqualifiedName;
+import org.eclipse.papyrus.alf.scoping.AlfScopeProvider;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.ElementImport;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TypedElement;
+
+public class TypeFacadeFactory {
+
+ public static TypeFacadeFactory eInstance = new TypeFacadeFactory() ;
+
+ public TypeFacade createTypeFacade(EObject typeObject) {
+ TypeFacade result = new TypeFacade() {
+ @Override
+ public String getLabelWithoutBinding() {
+ try {
+ if (typeObject instanceof Classifier)
+ return ((Classifier)typeObject).getName() ;
+ if (typeObject instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)typeObject ;
+ if (eImport.getAlias()!=null )
+ return eImport.getAlias() ;
+ else
+ return ((Classifier)eImport.getImportedElement()).getName() ;
+ }
+ if (typeObject instanceof Parameter) {
+ return ((Parameter)typeObject).getType().getName() ;
+ }
+ if (typeObject instanceof TypedElement) {
+ return ((TypedElement)typeObject).getType().getName() ;
+ }
+ if (typeObject instanceof SequenceExpansionExpression) {
+ TypeFacade t = TypeFacadeFactory.eInstance.createTypeFacade(typeObject) ;
+ return t.extractActualType().getName() ;
+ }
+ }
+ catch (NullPointerException e) { // occurs when no type can be derived from typeObject (i.e., typeObject.getType() == null)
+ return "any" ;
+ }
+ return super.getLabel() ;
+ }
+
+ @Override
+ public String getLabel() {
+ try {
+ if (typeObject instanceof Classifier)
+ return ((Classifier)typeObject).getName() + super.getLabel() ;
+ if (typeObject instanceof ElementImport) {
+ ElementImport eImport = (ElementImport)typeObject ;
+ if (eImport.getAlias()!=null )
+ return eImport.getAlias() + super.getLabel() ;
+ else
+ return ((Classifier)eImport.getImportedElement()).getName() + super.getLabel() ;
+ }
+ if (typeObject instanceof Parameter) {
+ return ((Parameter)typeObject).getType().getName() + super.getLabel() ;
+ }
+ if (typeObject instanceof TypedElement) {
+ return ((TypedElement)typeObject).getType().getName() + super.getLabel() ;
+ }
+ if (typeObject instanceof SequenceExpansionExpression) {
+ TypeFacade t = TypeFacadeFactory.eInstance.createTypeFacade(typeObject) ;
+ return t.extractActualType().getName() + super.getLabel() ;
+ }
+ if (typeObject == null)
+ return "any" ;
+ }
+ catch (NullPointerException e) { // occurs when no type can be derived from typeObject (i.e., typeObject.getType() == null)
+ return "any" ;
+ }
+ return super.getLabel() ;
+ }
+ };
+ if (typeObject instanceof Classifier)
+ result.setTypeObject(typeObject) ;
+ else if (typeObject instanceof ElementImport)
+ result.setTypeObject(typeObject) ;
+ else if (typeObject instanceof Parameter)
+ result.setTypeObject(typeObject) ;
+ else if (typeObject instanceof LocalNameDeclarationStatement) {
+ LocalNameDeclarationStatement statement = (LocalNameDeclarationStatement)typeObject ;
+ if (statement.getType() != null) {
+ result.setTypeObject(createVoidFacade(statement.getType()).typeObject);
+ }
+ }
+ else if (typeObject instanceof LoopVariableDefinition) {
+ LoopVariableDefinition loopVariable = (LoopVariableDefinition)typeObject ;
+ if (loopVariable.getType() != null) {
+ result.setTypeObject(createVoidFacade(loopVariable.getType()).typeObject) ;
+ }
+ else if (loopVariable.getExpression1() != null) {
+ TypeExpression typeOfExpression1 = new TypeUtils().getTypeOfExpression(loopVariable.getExpression1()) ;
+ if (loopVariable.getExpression2() != null) {
+ TypeExpression typeOfExpression2 = new TypeUtils().getTypeOfExpression(loopVariable.getExpression2()) ;
+ int _1_2_compatibility = typeOfExpression1.isCompatibleWithMe(typeOfExpression2) ;
+ int _2_1_compatibility = typeOfExpression2.isCompatibleWithMe(typeOfExpression1) ;
+ if (_1_2_compatibility == _2_1_compatibility) {
+ if (_1_2_compatibility != 0) {
+ result.setTypeObject(typeOfExpression1.getTypeFacade().typeObject) ;
+ }
+ }
+ else {
+ if (_1_2_compatibility > _2_1_compatibility)
+ result.setTypeObject(typeOfExpression1.getTypeFacade().typeObject) ;
+ else
+ result.setTypeObject(typeOfExpression2.getTypeFacade().typeObject) ;
+ }
+ }
+ else {
+ result.setTypeObject(typeOfExpression1.getTypeFacade().typeObject) ;
+ }
+ }
+ }
+ else if (typeObject instanceof Property) {
+ result.setTypeObject(typeObject) ;
+ }
+ else if (typeObject instanceof SequenceExpansionExpression) {
+ result.setTypeObject(typeObject) ;
+ }
+ else if (typeObject instanceof AcceptStatement) {
+ // first extract the accept clause
+ AcceptClause acceptClause = (AcceptClause)((AcceptStatement)typeObject).getClause() ;
+ if (acceptClause.getQualifiedNameList() != null && !(acceptClause.getQualifiedNameList().getQualifiedName().isEmpty())) {
+ // TODO : getQualifiedName is a collection. Should compute the least common ancestor.
+ TypeFacade f = TypeFacadeFactory.eInstance.createVoidFacade(acceptClause.getQualifiedNameList().getQualifiedName().get(0)) ;
+ result.setTypeObject(f.extractActualType()) ;
+ }
+ else {
+ result.setTypeObject(typeObject) ;
+ }
+ }
+ return result ;
+ }
+
+ public ErrorTypeFacade createErrorTypeFacade(String message, EObject source, EStructuralFeature structuralFeature) {
+ ErrorTypeFacade result = new ErrorTypeFacade() ;
+ result.setMessage(message) ;
+ result.setErrorSource(source) ;
+ result.setStructuralFeature(structuralFeature) ;
+ return result ;
+ }
+
+ public TypeFacade createVoidFacade(Expression exp) {
+ NameExpression actualNameExpression = null ;
+ for (Iterator<EObject> i = exp.eAllContents() ; i.hasNext() && actualNameExpression == null ; ) {
+ EObject o = i.next() ;
+ if (o instanceof NameExpression)
+ actualNameExpression = (NameExpression)o ;
+ }
+ if (actualNameExpression == null)
+ return createErrorTypeFacade("A type expression is expected", exp, AlfPackage.eINSTANCE.getConditionalTestExpression_Exp()) ;
+ else
+ return createVoidFacade(actualNameExpression) ;
+ }
+
+ public TypeFacade createVoidFacade(NameExpression exp) {
+ //if (! (exp.eContainer() instanceof ClassificationExpression ||
+ // exp.eContainer() instanceof SuperInvocationExpression ||
+ // exp.eContainer() instanceof InvocationOrAssignementOrDeclarationStatement)) {
+ // return createErrorTypeFacade("A type expression is expected", exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ //}
+ EObject previousPackage = null ;
+ if (exp.getPath() != null) {
+ List<UnqualifiedName> path = exp.getPath().getNamespace() ;
+ // first resolves the first element of the path
+ List<EObject> visiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(exp).resolveByName(path.get(0).getName()) ;
+ if (visiblePackages.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve package " + path.get(0).getName(), path.get(0), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ }
+ else if (visiblePackages.size() > 1) {
+ return createErrorTypeFacade(path.get(0).getName() + " resolves to multiple packages", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ }
+ else {
+ List<EObject> nestedVisiblePackages ;
+ previousPackage = visiblePackages.get(0) ;
+ for (int i = 1 ; i<path.size() ; i++) {
+ nestedVisiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(previousPackage).resolveByName(path.get(i).getName()) ;
+ if (nestedVisiblePackages.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve package " + path.get(i).getName(), path.get(i), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ }
+ else if (nestedVisiblePackages.size() > 1) {
+ return createErrorTypeFacade(path.get(i).getName() + " resolves to multiple packages", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ }
+ previousPackage = nestedVisiblePackages.get(0) ;
+ }
+ }
+ }
+ // At this point, the path has been validated, can check the final id.
+ EObject container = exp.eContainer() ;
+ if (container instanceof InvocationOrAssignementOrDeclarationStatement) {
+ InvocationOrAssignementOrDeclarationStatement cddDclStatement = (InvocationOrAssignementOrDeclarationStatement)container ;
+ if (cddDclStatement.getVariableDeclarationCompletion() != null) {
+ if (cddDclStatement.getTypePart_OR_assignedPart_OR_invocationPart().getSuffix() != null) {
+ return createErrorTypeFacade("A type expression is expected", cddDclStatement, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ;
+ }
+ if (exp.getInvocationCompletion() != null ||
+ exp.getPostfixOp() != null ||
+ exp.getPrefixOp() != null ||
+ exp.getSequenceConstructionCompletion() != null ) {// TODO: handle sequence constructions
+ return createErrorTypeFacade("A type expression is expected", cddDclStatement, AlfPackage.eINSTANCE.getInvocationOrAssignementOrDeclarationStatement_TypePart_OR_assignedPart_OR_invocationPart()) ;
+ }
+ List<EObject> visibleClassifiers = null ;
+
+ if (previousPackage == null)
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(exp.getId()) ;
+ else
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousPackage).resolveByName(exp.getId()) ;
+
+ if (visibleClassifiers.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve classifier " + exp.getId(), exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ }
+ else if (visibleClassifiers.size() > 1) {
+ return createErrorTypeFacade(exp.getId() + " resolves to multiple classifiers",
+ cddDclStatement, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ }
+ return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+ }
+ }
+ else if (container instanceof ClassificationExpression) {
+ // TODO
+ }
+ else if (container instanceof SuperInvocationExpression) {
+ // TODO: Not to be handled here => Should not resolve to a type
+ }
+ List<EObject> visibleClassifiers = null ;
+
+ if (previousPackage == null)
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(exp.getId()) ;
+ else
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousPackage).resolveByName(exp.getId()) ;
+
+ if (visibleClassifiers.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve classifier " + exp.getId(), exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ }
+ else if (visibleClassifiers.size() > 1) {
+ return createErrorTypeFacade(exp.getId() + " resolves to multiple classifiers",
+ exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ }
+ return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+ }
+
+
+
+ public TypeFacade createVoidFacade(QualifiedNameWithBinding exp) {
+ QualifiedNameWithBinding remaining = exp ;
+ EObject previousPackage = null ;
+ if (exp.getRemaining()!=null) { // A path is specified
+ List<EObject> visiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(exp).resolveByName(exp.getId()) ;
+ if (visiblePackages.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve package " + exp.getId(), exp, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
+ }
+ else if (visiblePackages.size() > 1) {
+ return createErrorTypeFacade(exp.getId() + " resolves to multiple packages", exp, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
+ }
+ else {
+ List<EObject> nestedVisiblePackages ;
+ previousPackage = visiblePackages.get(0) ;
+ remaining = exp.getRemaining() ;
+ while (remaining.getRemaining() != null) {
+ nestedVisiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(previousPackage).resolveByName(remaining.getId()) ;
+ if (nestedVisiblePackages.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve package " + remaining.getId(), remaining, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
+ }
+ else if (nestedVisiblePackages.size() > 1) {
+ return createErrorTypeFacade(remaining.getId() + " resolves to multiple packages", remaining, AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
+ }
+ previousPackage = nestedVisiblePackages.get(0) ;
+ remaining = remaining.getRemaining() ;
+ }
+ }
+ }
+ // At this point, the (potential) path has been validated, can check the final id.
+ // The last remaining.id should resolve to a classifier
+ List<EObject> visibleClassifiers = null ;
+ if (previousPackage != null)
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousPackage).resolveByName(remaining.getId()) ;
+ else
+ visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(remaining.getId()) ;
+ if (visibleClassifiers.isEmpty()) {
+ return createErrorTypeFacade("Could not resolve classifier " + remaining.getId(),remaining,
+ AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
+ }
+ else if (visibleClassifiers.size() > 1) {
+ return createErrorTypeFacade(remaining.getId() + " resolves to multiple classifiers.", remaining,
+ AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Id()) ;
+ }
+
+ // Need to check that potential binding is valid
+ Classifier resolvedClassifier = (Classifier)visibleClassifiers.get(0) ;
+ if (!resolvedClassifier.isTemplate()) {
+ if (remaining.getBinding()!= null) {
+ return createErrorTypeFacade(remaining.getId() + " is not a template", remaining,
+ AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ;
+ }
+ else {
+ return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+ }
+ }
+ else {
+ if (remaining.getBinding()!= null) {
+ // Needs to check that the binding is correct:
+ List<ParameterableElement> orderedListOfParameteredElements = new ArrayList<ParameterableElement>() ;
+ Map<String, ParameterableElement> mapOfParameteredElements = new HashMap<String, ParameterableElement>() ;
+ for (TemplateParameter tp : resolvedClassifier.getOwnedTemplateSignature().getOwnedParameters()) {
+ ParameterableElement p = tp.getParameteredElement() ;
+ if (p != null) {
+ orderedListOfParameteredElements.add(p) ;
+ mapOfParameteredElements.put(((NamedElement)p).getName(), p) ;
+ }
+ }
+ // Builds the substitutions map
+ Map<TemplateParameter, ParameterableElement> substitutionsMap = new HashMap<TemplateParameter, ParameterableElement>() ;
+ for (NamedTemplateBinding ntp : remaining.getBinding().getBindings()) {
+ ParameterableElement formal = mapOfParameteredElements.get(ntp.getFormal()) ;
+ if (formal == null) {
+ return createErrorTypeFacade("Template parameter " + ntp.getFormal() + " is undefined for classifier " + remaining.getId() , ntp,
+ AlfPackage.eINSTANCE.getNamedTemplateBinding_Formal()) ;
+ }
+ TypeFacade actual = createVoidFacade(ntp.getActual()) ;
+ if (actual instanceof ErrorTypeFacade)
+ return actual ;
+ substitutionsMap.put(formal.getTemplateParameter(), actual.extractActualType()) ;
+ }
+ // Checks the number of specified substitution
+ if (remaining.getBinding().getBindings().size() != orderedListOfParameteredElements.size()) {
+ String errorMessage = "" ;
+ if (remaining.getBinding().getBindings().size() > orderedListOfParameteredElements.size())
+ errorMessage = "Too many template bindings specified for " + remaining.getId() ;
+ else {
+ errorMessage = "Template bindings are missing for " + remaining.getId() ;
+ }
+ return createErrorTypeFacade(errorMessage, remaining,
+ AlfPackage.eINSTANCE.getQualifiedNameWithBinding_Binding()) ;
+ }
+ // Now, can create the void facade, and bind it with appropriate substitutions
+ VoidFacade boundResolvedClassifier = new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+// HashMap<Object, EObject> actualSubsitutionsMap = new HashMap<Object, EObject>() ;
+// for (ParameterableElement p : orderedListOfParameteredElements) {
+// actualSubsitutionsMap.put(TemplateBindingUtils.getParameteredElementName(p),
+// subsitutionsMap.get(p) ) ;
+// }
+ boundResolvedClassifier.bindTemplate(substitutionsMap) ;
+
+ return boundResolvedClassifier;
+ }
+ else {
+ // Binding is not specified. It is up to the caller to perform implicit bindings.
+ return new VoidFacade(createTypeFacade(visibleClassifiers.get(0))) ;
+ }
+ }
+ }
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java new file mode 100644 index 00000000000..ead36e1263d --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeInferenceException.java @@ -0,0 +1,41 @@ +package org.eclipse.papyrus.alf.validation.typing;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+
+public class TypeInferenceException extends Exception {
+
+ protected String errorMessage = "" ;
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ protected EObject errorSource = null ;
+ public EObject getErrorSource() {
+ return errorSource;
+ }
+
+ protected EStructuralFeature errorFeature = null ;
+ public EStructuralFeature getErrorFeature() {
+ return errorFeature;
+ }
+
+ public TypeInferenceException(TypeExpression typeOfArgument) {
+ // TODO Auto-generated constructor stub
+ if (typeOfArgument != null && typeOfArgument.getTypeFacade() != null) {
+ if (typeOfArgument.getTypeFacade() instanceof ErrorTypeFacade) {
+ ErrorTypeFacade e = (ErrorTypeFacade)typeOfArgument.getTypeFacade() ;
+ this.errorMessage += e.getLabel() ;
+ this.errorSource = e.getErrorSource() ;
+ this.errorFeature = e.getStructuralFeature() ;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -152485940032266338L;
+
+
+}
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java new file mode 100644 index 00000000000..c63e834dddc --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/TypeUtils.java @@ -0,0 +1,1799 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.papyrus.alf.alf.AdditiveExpression;
+import org.eclipse.papyrus.alf.alf.AlfPackage;
+import org.eclipse.papyrus.alf.alf.AndExpression;
+import org.eclipse.papyrus.alf.alf.BOOLEAN_LITERAL;
+import org.eclipse.papyrus.alf.alf.ClassExtentExpression;
+import org.eclipse.papyrus.alf.alf.ClassificationExpression;
+import org.eclipse.papyrus.alf.alf.CollectOrIterateOperation;
+import org.eclipse.papyrus.alf.alf.ConditionalAndExpression;
+import org.eclipse.papyrus.alf.alf.ConditionalOrExpression;
+import org.eclipse.papyrus.alf.alf.ConditionalTestExpression;
+import org.eclipse.papyrus.alf.alf.EqualityExpression;
+import org.eclipse.papyrus.alf.alf.ExclusiveOrExpression;
+import org.eclipse.papyrus.alf.alf.Expression;
+import org.eclipse.papyrus.alf.alf.ForAllOrExistsOrOneOperation;
+import org.eclipse.papyrus.alf.alf.INTEGER_LITERAL;
+import org.eclipse.papyrus.alf.alf.InclusiveOrExpression;
+import org.eclipse.papyrus.alf.alf.InstanceCreationExpression;
+import org.eclipse.papyrus.alf.alf.IsUniqueOperation;
+import org.eclipse.papyrus.alf.alf.LITERAL;
+import org.eclipse.papyrus.alf.alf.LinkOperationExpression;
+import org.eclipse.papyrus.alf.alf.MultiplicativeExpression;
+import org.eclipse.papyrus.alf.alf.NameExpression;
+import org.eclipse.papyrus.alf.alf.NonLiteralValueSpecification;
+import org.eclipse.papyrus.alf.alf.NullExpression;
+import org.eclipse.papyrus.alf.alf.OperationCallExpression;
+import org.eclipse.papyrus.alf.alf.Tuple;
+//import org.eclipse.papyrus.alf.alf.OperationCallExpressionWithoutDot;
+import org.eclipse.papyrus.alf.alf.ParenthesizedExpression;
+import org.eclipse.papyrus.alf.alf.PrimaryExpression;
+import org.eclipse.papyrus.alf.alf.PropertyCallExpression;
+import org.eclipse.papyrus.alf.alf.RelationalExpression;
+import org.eclipse.papyrus.alf.alf.STRING_LITERAL;
+import org.eclipse.papyrus.alf.alf.SelectOrRejectOperation;
+import org.eclipse.papyrus.alf.alf.SequenceConstructionExpression;
+import org.eclipse.papyrus.alf.alf.SequenceConstructionOrAccessCompletion;
+import org.eclipse.papyrus.alf.alf.SequenceElement;
+import org.eclipse.papyrus.alf.alf.SequenceExpansionExpression;
+import org.eclipse.papyrus.alf.alf.SequenceOperationExpression;
+import org.eclipse.papyrus.alf.alf.SequenceReductionExpression;
+import org.eclipse.papyrus.alf.alf.ShiftExpression;
+import org.eclipse.papyrus.alf.alf.SuffixExpression;
+import org.eclipse.papyrus.alf.alf.SuperInvocationExpression;
+import org.eclipse.papyrus.alf.alf.ThisExpression;
+import org.eclipse.papyrus.alf.alf.TupleElement;
+import org.eclipse.papyrus.alf.alf.UNLIMITED_LITERAL;
+import org.eclipse.papyrus.alf.alf.UnaryExpression;
+import org.eclipse.papyrus.alf.alf.UnqualifiedName;
+import org.eclipse.papyrus.alf.alf.ValueSpecification;
+import org.eclipse.papyrus.alf.scoping.AlfScopeProvider;
+import org.eclipse.papyrus.alf.validation.AlfJavaValidator;
+import org.eclipse.uml2.uml.Behavior;
+import org.eclipse.uml2.uml.Classifier;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.Operation;
+import org.eclipse.uml2.uml.Parameter;
+import org.eclipse.uml2.uml.ParameterDirectionKind;
+import org.eclipse.uml2.uml.ParameterableElement;
+import org.eclipse.uml2.uml.PrimitiveType;
+import org.eclipse.uml2.uml.TemplateParameter;
+import org.eclipse.uml2.uml.TemplateableElement;
+
+public class TypeUtils {
+
+ public static TypeFacade _undefined ;
+ public static TypeFacade _integer ;
+ public static TypeFacade _boolean ;
+ public static TypeFacade _unlimited ;
+ public static TypeFacade _natural ;
+ public static TypeFacade _string ;
+ public static TypeFacade _bitString ;
+ public static TypeExpression _nullExpression ;
+ public static TypeFacade _Collection ;
+ public static TypeFacade _Set ;
+ public static TypeFacade _Bag ;
+ public static TypeFacade _Queue ;
+ public static TypeFacade _OrderedSet ;
+ public static TypeFacade _List ;
+ public static TypeFacade _Deque ;
+ public static TypeFacade _Map ;
+ public static TypeFacade _Entry ;
+ public static Map<String, SignatureFacade> predefinedCollectionFunctions ;
+
+
+ private SuffixExpression suffixToBeIgnored = null ;
+
+ public TypeUtils() {
+
+ }
+
+ public TypeUtils(SuffixExpression suffixToBeIgnored) {
+ this.suffixToBeIgnored = suffixToBeIgnored ;
+ }
+
+ public TypeExpression getTypeOfExpression(Expression exp) {
+ return getTypeOfConditionalTestExpression((ConditionalTestExpression)exp) ;
+ }
+
+ public TypeExpression getTypeOfConditionalTestExpression(ConditionalTestExpression exp) {
+ if (exp.getWhenTrue() != null) {
+ TypeExpression typeOfCondition = getTypeOfConditionalOrExpression(exp.getExp()) ;
+ if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade) {
+ ErrorTypeFacade error = (ErrorTypeFacade)typeOfCondition.getTypeFacade() ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ if (TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean).isCompatibleWithMe(typeOfCondition) != 3) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("An expression of type Boolean is expected. Found an expression of type " + typeOfCondition.getLabel(), exp, AlfPackage.eINSTANCE.getConditionalTestExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ }
+ TypeExpression typeOfWhenTrue = getTypeOfConditionalTestExpression(exp.getWhenTrue()) ;
+ if (typeOfWhenTrue.getTypeFacade() instanceof ErrorTypeFacade) {
+ ErrorTypeFacade error = (ErrorTypeFacade)typeOfWhenTrue.getTypeFacade() ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ if (exp.getWhenFalse() == null) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("The \'when false\' alternative is missing", exp, AlfPackage.eINSTANCE.getConditionalTestExpression_WhenFalse()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ TypeExpression typeOfWhenFalse = getTypeOfConditionalTestExpression(exp.getWhenFalse()) ;
+ if (typeOfWhenFalse.getTypeFacade() instanceof ErrorTypeFacade) {
+ ErrorTypeFacade error = (ErrorTypeFacade)typeOfWhenFalse.getTypeFacade() ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ int falseTrueCompatibility = typeOfWhenFalse.isCompatibleWithMe(typeOfWhenTrue) ;
+ int trueFalseCompatibility = typeOfWhenTrue.isCompatibleWithMe(typeOfWhenFalse) ;
+ if (falseTrueCompatibility == trueFalseCompatibility) {
+ if (falseTrueCompatibility == 0) {// No type compatibility between the two alternatives
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("The \'when true\' and \'when false\' alternatives must be type compatible", exp, AlfPackage.eINSTANCE.getConditionalTestExpression_WhenTrue()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else
+ return typeOfWhenTrue ;
+ }
+ else if (falseTrueCompatibility > trueFalseCompatibility)
+ return typeOfWhenFalse ;
+ else // falseTrueCompatibility < trueFalseCompatibility
+ return typeOfWhenTrue ;
+ }
+ }
+ }
+ return getTypeOfConditionalOrExpression((ConditionalOrExpression)exp.getExp()) ;
+ }
+
+ public TypeExpression getTypeOfConditionalOrExpression(ConditionalOrExpression exp) {
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfConditionalAndExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ else if (TypeExpressionFactory.eInstance.createTypeExpression(_boolean).isCompatibleWithMe(previous) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Expecting an expression of type Boolean. Found an expression of type " + previous.getLabel(), exp, AlfPackage.eINSTANCE.getConditionalAndExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfConditionalAndExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ else if (TypeExpressionFactory.eInstance.createTypeExpression(_boolean).isCompatibleWithMe(current) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Operator || is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")", exp, AlfPackage.eINSTANCE.getConditionalAndExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ previous = current ;
+ }
+ return current ;
+ }
+ return getTypeOfConditionalAndExpression((ConditionalAndExpression)exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfConditionalAndExpression(ConditionalAndExpression exp) {
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfInclusiveOrExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ else if (TypeExpressionFactory.eInstance.createTypeExpression(_boolean).isCompatibleWithMe(previous) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Expecting an expression of type Boolean. Found an expression of type " + previous.getLabel(), exp, AlfPackage.eINSTANCE.getConditionalAndExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfInclusiveOrExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ else if (TypeExpressionFactory.eInstance.createTypeExpression(_boolean).isCompatibleWithMe(current) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Operator && is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")", exp, AlfPackage.eINSTANCE.getConditionalAndExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ previous = current ;
+ }
+ return current ;
+ }
+ return getTypeOfInclusiveOrExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfInclusiveOrExpression(InclusiveOrExpression exp) {
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfExclusiveOrExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfExclusiveOrExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ argumentTypes.add(current) ;
+ List<SignatureFacade> availableSignatures = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures("|") ;
+ List<SignatureFacade> applicableSignatures = SignatureFacade.findNearestSignature(argumentTypes, availableSignatures) ;
+ if (applicableSignatures.isEmpty() || applicableSignatures.size()>1 ) {
+ String message = "Operator | is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")";
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(message, exp, AlfPackage.eINSTANCE.getExclusiveOrExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else
+ current = applicableSignatures.get(0).getReturnType() ;
+ previous = current ;
+ }
+ return current ;
+ }
+ return getTypeOfExclusiveOrExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfExclusiveOrExpression(ExclusiveOrExpression exp) {
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfAndExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfAndExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ argumentTypes.add(current) ;
+ List<SignatureFacade> availableSignatures = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures("^") ;
+ List<SignatureFacade> applicableSignatures = SignatureFacade.findNearestSignature(argumentTypes, availableSignatures) ;
+ if (applicableSignatures.isEmpty() || applicableSignatures.size()>1 ) {
+ String message = "Operator ^ is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")";
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(message, exp, AlfPackage.eINSTANCE.getExclusiveOrExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else
+ current = applicableSignatures.get(0).getReturnType() ;
+ previous = current ;
+ }
+ return current ;
+ }
+ return getTypeOfAndExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfAndExpression(AndExpression exp) {
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfEqualityExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfEqualityExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ argumentTypes.add(current) ;
+ List<SignatureFacade> availableSignatures = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures("&") ;
+ List<SignatureFacade> applicableSignatures = SignatureFacade.findNearestSignature(argumentTypes, availableSignatures) ;
+ if (applicableSignatures.isEmpty() || applicableSignatures.size()>1 ) {
+ String message = "Operator & is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")";
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(message, exp, AlfPackage.eINSTANCE.getAndExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else
+ current = applicableSignatures.get(0).getReturnType() ;
+ previous = current ;
+ }
+ return current ;
+ }
+ return getTypeOfEqualityExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfEqualityExpression(EqualityExpression exp) {
+ if (exp.getExp().size() > 1) {
+ for (ClassificationExpression classificationExp : exp.getExp()) {
+ TypeExpression argType = getTypeOfClassificationExpression(classificationExp) ;
+ if (argType.getTypeFacade() instanceof ErrorTypeFacade)
+ return argType ;
+ }
+ return TypeExpressionFactory.eInstance.createTypeExpression(_boolean);
+ }
+ return getTypeOfClassificationExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfClassificationExpression(ClassificationExpression exp) {
+ if (exp.getOp() != null) {
+ TypeExpression typeOfClassifiedPart = getTypeOfRelationalExpression(exp.getExp()) ;
+ if (typeOfClassifiedPart.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfClassifiedPart ;
+ TypeFacade typeOfClassificationPart = TypeFacadeFactory.eInstance.createVoidFacade(exp.getTypeName()) ;
+ if (typeOfClassificationPart instanceof ErrorTypeFacade)
+ return TypeExpressionFactory.eInstance.createTypeExpression(typeOfClassificationPart) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(_boolean);
+ }
+ return getTypeOfRelationalExpression(exp.getExp()) ;
+ }
+
+ public TypeExpression getTypeOfRelationalExpression(RelationalExpression exp) {
+ if (exp.getOp() != null) {
+ TypeExpression typeOfLeft = getTypeOfShiftExpression(exp.getLeft()) ;
+ if (typeOfLeft.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfLeft ;
+ if (exp.getRight() != null) {
+ TypeExpression typeOfRight = getTypeOfShiftExpression(exp.getRight()) ;
+ if (typeOfRight.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfRight ;
+ List<SignatureFacade> availableSignatures = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(exp.getOp()) ;
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(typeOfLeft) ;
+ argumentTypes.add(typeOfRight) ;
+ List<SignatureFacade> applicableSignatures = SignatureFacade.findNearestSignature(argumentTypes, availableSignatures) ;
+ if (applicableSignatures.isEmpty() || applicableSignatures.size()>1) {
+ String message = "Operator " + exp.getOp() + " is undefined for (" + typeOfLeft.getLabel() + ", " + typeOfRight.getLabel() + ")";
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(message, exp, AlfPackage.eINSTANCE.getRelationalExpression_Op()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ return applicableSignatures.get(0).getReturnType() ;
+ }
+
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Right operand missing", exp, AlfPackage.eINSTANCE.getRelationalExpression_Left()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ return getTypeOfShiftExpression(exp.getLeft()) ;
+ }
+
+ public TypeExpression getTypeOfShiftExpression(ShiftExpression exp) {
+ if (exp.getOp() != null) {
+ if (exp.getExp().size() == 2) {
+ TypeExpression typeOfLeft = getTypeOfAdditiveExpression(exp.getExp().get(0)) ;
+ if (typeOfLeft.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfLeft ;
+ TypeExpression typeOfRight = getTypeOfAdditiveExpression(exp.getExp().get(1)) ;
+ if (typeOfRight.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfRight ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(_bitString); // TODO: rely on PrimitiveBehaviors as soon as AlfLibrary is complete
+ }
+ else if (exp.getExp().size() == 1) {
+ TypeExpression typeOfLeft = getTypeOfAdditiveExpression(exp.getExp().get(0)) ;
+ if (typeOfLeft.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfLeft ;
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Right operand missing", exp, AlfPackage.eINSTANCE.getShiftExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ return getTypeOfAdditiveExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfAdditiveExpression(AdditiveExpression exp) {
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfMultiplicativeExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfMultiplicativeExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ argumentTypes.add(current) ;
+ List<SignatureFacade> availableSignatures = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(exp.getOp().get(i-1)) ;
+ List<SignatureFacade> applicableSignatures = SignatureFacade.findNearestSignature(argumentTypes, availableSignatures) ;
+ if (applicableSignatures.isEmpty() || applicableSignatures.size()>1 ) {
+ String message = "Operator " + exp.getOp().get(i-1) + " is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")";
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(message, exp, AlfPackage.eINSTANCE.getAdditiveExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else
+ current = applicableSignatures.get(0).getReturnType() ;
+ previous = current ;
+ }
+ return current ;
+ }
+ return getTypeOfMultiplicativeExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfMultiplicativeExpression(MultiplicativeExpression exp) {
+ if (exp.getExp() == null || exp.getExp().size() == 0)
+ return TypeExpressionFactory.eInstance.createTypeExpression(_undefined) ;
+ if (exp.getExp().size() > 1) {
+ TypeExpression previous = getTypeOfUnaryExpression(exp.getExp().get(0)) ;
+ if (previous.getTypeFacade() instanceof ErrorTypeFacade)
+ return previous ;
+ TypeExpression current = null ;
+ for (int i = 1 ; i<exp.getExp().size() ; i++) {
+ List<TypeExpression> argumentTypes = new ArrayList<TypeExpression>() ;
+ argumentTypes.add(previous) ;
+ current = getTypeOfUnaryExpression(exp.getExp().get(i)) ;
+ if (current.getTypeFacade() instanceof ErrorTypeFacade)
+ return current ;
+ argumentTypes.add(current) ;
+ List<SignatureFacade> availableSignatures = AlfJavaValidator.predefinedBehaviorsAndTypes.getSignatures(exp.getOp().get(i-1)) ;
+ List<SignatureFacade> applicableSignatures = SignatureFacade.findNearestSignature(argumentTypes, availableSignatures) ;
+ if (applicableSignatures.isEmpty() || applicableSignatures.size()>1) {
+ String message = "Operator " + exp.getOp().get(i-1) + " is undefined for (" + previous.getLabel() + ", " + current.getLabel() + ")";
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(message, exp, AlfPackage.eINSTANCE.getMultiplicativeExpression_Exp()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else
+ current = applicableSignatures.get(0).getReturnType() ;
+ previous = current ;
+ }
+
+ return current ;
+ }
+ return getTypeOfUnaryExpression(exp.getExp().get(0)) ;
+ }
+
+ public TypeExpression getTypeOfUnaryExpression(UnaryExpression exp) {
+ TypeExpression typeOfExp = getTypeOfPrimaryExpression(exp.getExp()) ;
+ if (typeOfExp.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfExp ;
+ if (exp.getOp() != null) {
+ // '!'|'-'|'+'|'$'|'~'
+ if (exp.getOp().equals("!")) {
+ TypeExpression booleanExpression = TypeExpressionFactory.eInstance.createTypeExpression(_boolean) ;
+ if (booleanExpression.isCompatibleWithMe(typeOfExp) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Unrary operator ! does not apply to " + typeOfExp.getLabel(),
+ exp,
+ AlfPackage.eINSTANCE.getUnaryExpression_Op()) ;
+ typeOfExp = TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ else if (exp.getOp().equals("-") || exp.getOp().equals("+")) {
+ TypeExpression integerExpression = TypeExpressionFactory.eInstance.createTypeExpression(_integer) ;
+ TypeExpression naturalExpression = TypeExpressionFactory.eInstance.createTypeExpression(_natural) ;
+ TypeExpression unlimitedExpression = TypeExpressionFactory.eInstance.createTypeExpression(_unlimited) ;
+ if (! (integerExpression.isCompatibleWithMe(typeOfExp)!=0 ||
+ naturalExpression.isCompatibleWithMe(typeOfExp) !=0 ||
+ unlimitedExpression.isCompatibleWithMe(typeOfExp) !=0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Unary operator " + exp.getOp() + " does not apply to "+ typeOfExp.getLabel(),
+ exp,
+ AlfPackage.eINSTANCE.getUnaryExpression_Op()) ;
+ typeOfExp = TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ else if (exp.getOp().equals("$")) {
+ // Nothing special to do here
+ }
+ else if (exp.getOp().equals("~")) {
+ TypeExpression integerExpression = TypeExpressionFactory.eInstance.createTypeExpression(_integer) ;
+ TypeExpression bitstringExpression = TypeExpressionFactory.eInstance.createTypeExpression(_bitString) ;
+ if (! (integerExpression.isCompatibleWithMe(typeOfExp)!=0 ||
+ bitstringExpression.isCompatibleWithMe(typeOfExp) !=0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Unary operator " + exp.getOp() + " does not apply to "+ typeOfExp.getLabel(),
+ exp,
+ AlfPackage.eINSTANCE.getUnaryExpression_Op()) ;
+ typeOfExp = TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Undefined unary operator",
+ exp,
+ AlfPackage.eINSTANCE.getUnaryExpression_Op()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ }
+ return typeOfExp ;
+ }
+
+ public TypeExpression getTypeOfPrimaryExpression(PrimaryExpression exp) {
+ return getTypeOfValueSpecification(exp.getPrefix()) ;
+ }
+
+ public TypeExpression getTypeOfValueSpecification(ValueSpecification exp) {
+ TypeExpression type = null ;
+ if (exp instanceof NameExpression)
+ type = getTypeOfNameExpression((NameExpression)exp) ;
+ else if (exp instanceof LITERAL)
+ type = getTypeOfLITERAL((LITERAL)exp);
+ else if (exp instanceof ThisExpression)
+ type = getTypeOfThisExpression((ThisExpression)exp);
+ else if (exp instanceof SuperInvocationExpression)
+ type = getTypeOfSuperInvocationExpression((SuperInvocationExpression)exp);
+ else if (exp instanceof InstanceCreationExpression)
+ type = getTypeOfInstanceCreationExpression((InstanceCreationExpression)exp) ;
+ else if (exp instanceof ParenthesizedExpression)
+ type = getTypeOfParenthesizedExpression((ParenthesizedExpression)exp) ;
+ else if (exp instanceof NullExpression)
+ type = getTypeOfNullExpression((NullExpression)exp) ;
+ return type ;
+ }
+
+ public TypeExpression getTypeOfNullExpression(NullExpression exp) {
+ return TypeUtils._nullExpression ;
+ }
+
+ public TypeExpression getTypeOfInstanceCreationExpression(InstanceCreationExpression exp) {
+ if (exp.getTuple() != null) {
+ // first try to determine if the expression directly refers to a Class or a DataType
+ try {
+ SignatureFacade s = SignatureFacadeFactory.eInstance.createConstructorFacade(exp) ;
+ if (s.hasReturnType()) {
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored) {
+ return getTypeOfSuffixExpression(exp.getSuffix(), s.getReturnType()) ;
+ }
+ return s.getReturnType() ;
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Constructor " + exp.getConstructor().getId() + " is illformed (no return type defined)",
+ exp,
+ AlfPackage.eINSTANCE.getInstanceCreationExpression_Constructor()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ catch (Exception e) {
+ ErrorTypeFacade error = null ;
+ if (e instanceof TypeInferenceException) {
+ TypeInferenceException tie = (TypeInferenceException)e ;
+ error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ tie.getErrorMessage(),
+ tie.getErrorSource(),
+ tie.getErrorFeature()) ;
+ }
+ else {
+ error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ e.getMessage(),
+ exp,
+ AlfPackage.eINSTANCE.getInstanceCreationExpression_Constructor()) ;
+ }
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "An instance creation or sequence creation is expected",
+ exp,
+ AlfPackage.eINSTANCE.getInstanceCreationExpression_Constructor()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+
+ public TypeExpression getTypeOfSuperInvocationExpression(SuperInvocationExpression exp) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "SuperInvocationExpression are not supported in this version of the Alf editor",
+ exp,
+ AlfPackage.eINSTANCE.getSuperInvocationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ public TypeExpression getTypeOfNonLiteralValueSpecification(NonLiteralValueSpecification exp) {
+ if (exp instanceof NameExpression)
+ return getTypeOfNameExpression((NameExpression)exp) ;
+ if (exp instanceof ThisExpression)
+ return getTypeOfThisExpression((ThisExpression)exp);
+ if (exp instanceof SuperInvocationExpression)
+ return getTypeOfSuperInvocationExpression((SuperInvocationExpression)exp) ;
+ if (exp instanceof InstanceCreationExpression)
+ return getTypeOfInstanceCreationExpression((InstanceCreationExpression)exp) ;
+ if (exp instanceof ParenthesizedExpression)
+ return getTypeOfParenthesizedExpression((ParenthesizedExpression)exp) ;
+ return null ;
+ }
+
+ public TypeExpression getTypeOfLITERAL(LITERAL exp) {
+ TypeFacade t = _undefined ;
+ if (exp instanceof BOOLEAN_LITERAL)
+ t = _boolean ;
+ else if (exp instanceof STRING_LITERAL)
+ t = _string ;
+ else if (exp instanceof INTEGER_LITERAL)
+ t = _integer ;
+ else if (exp instanceof UNLIMITED_LITERAL)
+ t = _unlimited ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(t) ;
+ }
+
+ public TypeExpression getTypeOfParenthesizedExpression(ParenthesizedExpression exp) {
+ if (exp.getCasted() != null) // && exp.getSuffix() == null)
+ return getTypeOfCastExpression(exp) ;
+ TypeExpression typeOfParenthesizedExpression = getTypeOfExpression((Expression)exp.getExpOrTypeCast()) ;
+ if (typeOfParenthesizedExpression.getTypeFacade() instanceof ErrorTypeFacade) {
+ return typeOfParenthesizedExpression ;
+ }
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfParenthesizedExpression) ;
+ return typeOfParenthesizedExpression ;
+ }
+
+ protected TypeExpression getTypeOfCastExpression(ParenthesizedExpression exp) {
+ TypeExpression typeOfCastedPart = getTypeOfNonLiteralValueSpecification(exp.getCasted()) ;
+ if (typeOfCastedPart.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfCastedPart ;
+ TypeFacade castingTypeFacade = TypeFacadeFactory.eInstance.createVoidFacade(exp.getExpOrTypeCast()) ;
+ TypeExpression result = new TypeExpression() ;
+ result.setType(castingTypeFacade) ;
+ result.setMultiplicity(typeOfCastedPart.getMultiplicity()) ;
+ return result ;
+ }
+
+ protected boolean isACastExpression(NameExpression exp) {
+ EObject container = exp.eContainer() ;
+ EObject cddCastingPart = exp ;
+ while (container != null && ! (container instanceof ParenthesizedExpression)) {
+ cddCastingPart = container ;
+ container = container.eContainer() ;
+ }
+ if (container == null)
+ return false ;
+ else {
+ ParenthesizedExpression cddCastExpression = (ParenthesizedExpression)container ;
+ if (cddCastingPart.eContainingFeature() == AlfPackage.eINSTANCE.getParenthesizedExpression_ExpOrTypeCast())
+ return cddCastExpression.getCasted() != null ;
+ else
+ return false ;
+ }
+ }
+
+ public TypeExpression getTypeOfNameExpression(NameExpression exp) {
+ //
+ //if (exp.eContainer() instanceof ClassificationExpression ||
+ // exp.eContainer() instanceof SuperInvocationExpression ||
+ // exp.eContainer() instanceof InvocationOrAssignementOrDeclarationStatement ||
+ // isACastExpression(exp)) {
+ // return TypeExpressionFactory.eInstance.createTypeExpression(_undefined);
+ //}
+
+
+
+ EObject previousPackage = null ;
+ if (exp.getPath() != null) {
+ List<UnqualifiedName> path = exp.getPath().getNamespace() ;
+ // first resolves the first element of the path
+ List<EObject> visiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(exp).resolveByName(path.get(0).getName()) ;
+ if (visiblePackages.isEmpty()) {
+ // Try to find a classifier
+ List<EObject> visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(path.get(0).getName()) ;
+ if (visibleClassifiers.isEmpty()) {
+ // No classifier found
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve package " + path.get(0).getName(), path.get(0), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(0).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ // Then walks through the path, which shall contain only references to (nested) classifiers
+ List<EObject> nestedVisibleClassifiers ;
+ EObject previousClassifier = visibleClassifiers.get(0) ;
+ for (int i = 1 ; i<path.size() ; i++) {
+ nestedVisibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousClassifier).resolveByName(path.get(i).getName()) ;
+ if (nestedVisibleClassifiers.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve classifier " + path.get(i).getName(), path.get(i), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (nestedVisibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(i).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ previousClassifier = nestedVisibleClassifiers.get(0) ;
+ }
+ // TODO : Check if this is reasonable => We make the assumption than the final id can only be a reference to an enumeration
+ if (previousClassifier instanceof Enumeration) {
+ List<EObject> visibleEnumerationLiterals = AlfScopeProvider.scopingTool.getVisibleEnumerationLiterals(previousClassifier).resolveByName(exp.getId()) ;
+ if (visibleEnumerationLiterals.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve enumeration literal " + exp.getId(), exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleEnumerationLiterals.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(exp.getId() + " resolves to multiple enumeration literals", exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ return TypeExpressionFactory.eInstance.createTypeExpression(previousClassifier) ;
+ }
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(path.size()-1).getName() + " does not resolve to an enumeration", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ }
+ }
+ else if (visiblePackages.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(0).getName() + " resolves to multiple packages", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ List<EObject> nestedVisiblePackages ;
+ previousPackage = visiblePackages.get(0) ;
+ for (int i = 1 ; i<path.size() ; i++) {
+ nestedVisiblePackages = AlfScopeProvider.scopingTool.getVisiblePackages(previousPackage).resolveByName(path.get(i).getName()) ;
+ if (nestedVisiblePackages.isEmpty()) {
+ // Try to find a classifier
+ List<EObject> visibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(exp).resolveByName(path.get(i).getName()) ;
+ if (visibleClassifiers.isEmpty()) {
+ // No classifier found
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve package " + path.get(i).getName(), path.get(i), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(0).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ // Then walks through the path, which shall contain only references to (nested) classifiers
+ List<EObject> nestedVisibleClassifiers ;
+ EObject previousClassifier = visibleClassifiers.get(0) ;
+ for (int j = i ; j<path.size() ; j++) {
+ nestedVisibleClassifiers = AlfScopeProvider.scopingTool.getVisibleClassifiers(previousClassifier).resolveByName(path.get(j).getName()) ;
+ if (nestedVisibleClassifiers.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve classifier " + path.get(j).getName(), path.get(j), AlfPackage.eINSTANCE.getUnqualifiedName_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (nestedVisibleClassifiers.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(j).getName() + " resolves to multiple classifiers", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ previousClassifier = nestedVisibleClassifiers.get(0) ;
+ }
+ // TODO : Check if this is reasonable => We make the assumption than the final id can only be a reference to an enumeration
+ if (previousClassifier instanceof Enumeration) {
+ List<EObject> visibleEnumerationLiterals = AlfScopeProvider.scopingTool.getVisibleEnumerationLiterals(previousClassifier).resolveByName(exp.getId()) ;
+ if (visibleEnumerationLiterals.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade("Could not resolve enumeration literal " + exp.getId(), exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleEnumerationLiterals.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(exp.getId() + " resolves to multiple enumeration literals", exp, AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ return TypeExpressionFactory.eInstance.createTypeExpression(previousClassifier) ;
+ }
+ }
+ else {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(path.size()-1).getName() + " does not resolve to an enumeration", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ }
+ }
+ else if (nestedVisiblePackages.size() > 1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(path.get(i).getName() + " resolves to multiple packages", exp.getPath(), AlfPackage.eINSTANCE.getQualifiedNamePath_Namespace()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ previousPackage = nestedVisiblePackages.get(0) ;
+ }
+ }
+ }
+
+ // TODO handle the case of a sequence construction expression
+
+ TypeExpression typeOfPrefix = null ;
+
+ if (exp.getPath() == null) {
+ if (exp.getInvocationCompletion()==null) { // && exp.getSequenceConstructionCompletion() == null) {
+ List<EObject> visibleVariableOrParametersOrProperties = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(exp).resolveByName(exp.getId()) ;
+ if (visibleVariableOrParametersOrProperties.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Could not resolve local variable, property or parameter " + exp.getId(),
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (visibleVariableOrParametersOrProperties.size()>1) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ exp.getId() + " resolves to multiple elements",
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else {
+ EObject resolved = visibleVariableOrParametersOrProperties.get(0) ;
+ typeOfPrefix = TypeExpressionFactory.eInstance.createTypeExpression(resolved) ;
+ }
+ }
+ }
+ else {
+ // TODO: Handle associations here ?
+ // TODO: Handle ClassExtent here ?
+ }
+
+ if (exp.getInvocationCompletion()!=null ) { //&& exp.getSequenceConstructionCompletion() == null ) {
+ List<TypeExpression> arguments = new ArrayList<TypeExpression>() ;
+ for (TupleElement e : exp.getInvocationCompletion().getTupleElements()) {
+ TypeExpression type = getTypeOfExpression(e.getArgument()) ;
+ if (type.getTypeFacade() != null && type.getTypeFacade() instanceof ErrorTypeFacade)
+ return type ;
+ arguments.add(type) ;
+ }
+ List<EObject> visibleOperationOrBehaviors = AlfScopeProvider.scopingTool.getVisibleOperationsOrBehaviors(previousPackage != null ? previousPackage : exp).resolveByName(exp.getId()) ;
+ if (visibleOperationOrBehaviors.isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Could not resolve operation or behavior " + exp.getId(),
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else if (visibleOperationOrBehaviors.size()>1) {
+ List<SignatureFacade> availableSignatures = new ArrayList<SignatureFacade>() ;
+ for (EObject operation : visibleOperationOrBehaviors) {
+ availableSignatures.add(SignatureFacadeFactory.eInstance.createSignatureFacade(operation)) ;
+ }
+ List<SignatureFacade> selectedSignatures = SignatureFacade.findNearestSignature(arguments, availableSignatures) ;
+ if (selectedSignatures.size() > 1) { // could not infer the actual operations even with type of arguments
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ exp.getId() + " resolves to multiple elements",
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (selectedSignatures.size() == 0) {
+ String errorMessage = exp.getId() + " does not apply to arguments (" ;
+ boolean first = true ;
+ for (TypeExpression argType : arguments) {
+ if (!first)
+ errorMessage += ", " ;
+ else
+ first = false ;
+ errorMessage += argType.getLabel() ;
+ }
+ errorMessage += ")" ;
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ errorMessage,
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_Id()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ typeOfPrefix = selectedSignatures.get(0).getReturnType() ;
+ }
+ }
+ else {
+ SignatureFacade operationOrBehaviorSignature = SignatureFacadeFactory.eInstance.createSignatureFacade(visibleOperationOrBehaviors.get(0)) ;
+ String argumentsAreCompatible = operationOrBehaviorSignature.isCompatibleWithMe(arguments, true) ;
+ if (! (argumentsAreCompatible.length() == 0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ argumentsAreCompatible,
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_InvocationCompletion()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ typeOfPrefix = operationOrBehaviorSignature.getReturnType() ;
+ }
+ }
+
+ if (exp.getSequenceConstructionCompletion() != null) {
+ SequenceConstructionOrAccessCompletion sequenceAccessOrConstruction = exp.getSequenceConstructionCompletion() ;
+ if (sequenceAccessOrConstruction.getAccessCompletion() != null) {
+ int prefixUpperBound = typeOfPrefix.getMultiplicity().getUpperBound() ;
+ boolean prefixIsOrdered = typeOfPrefix.getMultiplicity().isOrdered() ;
+ if (! (prefixUpperBound == -1 || prefixUpperBound > 1)) {
+ String errorMessage = "Unexpected index. " + exp.getId() + " is not a collection." ;
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ errorMessage,
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_SequenceConstructionCompletion()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else if (!prefixIsOrdered){
+ String errorMessage = "Unexpected index. " + exp.getId() + " is not ordered." ;
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ errorMessage,
+ exp,
+ AlfPackage.eINSTANCE.getNameExpression_SequenceConstructionCompletion()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ TypeExpression typeOfIndex = getTypeOfExpression(sequenceAccessOrConstruction.getAccessCompletion().getAccessIndex()) ;
+ if (typeOfIndex.getTypeFacade() instanceof ErrorTypeFacade) {
+ return typeOfIndex ;
+ }
+ else if (! (_integer.isCompatibleWithMe(typeOfIndex.getTypeFacade())== 3 || _natural.isCompatibleWithMe(typeOfIndex.getTypeFacade())==3)) {
+ String errorMessage = "Expecting an expression of type Integer. Found an expression of type " + typeOfIndex.getLabel() ;
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ errorMessage,
+ sequenceAccessOrConstruction,
+ AlfPackage.eINSTANCE.getAccessCompletion_AccessIndex()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ // need to change the multiplicity of typeOfPrefix
+ //typeOfPrefix.setMultiplicity(MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(0, 1, false, false)) ;
+ typeOfPrefix.setMultiplicity(MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(1, 1, false, false)) ; // TODO: 1..1 is temporary
+ }
+ }
+ }
+
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored) {
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfPrefix) ;
+ }
+ return typeOfPrefix ;
+ }
+
+ public TypeExpression getTypeOfThisExpression(ThisExpression exp) {
+ TypeExpression typeOfPrefix = TypeExpressionFactory.eInstance.createTypeExpression(AlfJavaValidator.getContextClassifier()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored) {
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfPrefix) ;
+ }
+ return typeOfPrefix ;
+ }
+
+ public TypeExpression getTypeOfSuffixExpression(SuffixExpression exp, TypeExpression propagatedTypeOfPrefix) {
+ // TODO: Support all cases
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ ///////////////////////////
+
+ TypeExpression typeOfPrefix = propagatedTypeOfPrefix ;
+
+ if (typeOfPrefix == null) {
+ String errorMessage = "Type of prefix is undefined. Could not validate suffix." ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else if (typeOfPrefix.getTypeFacade() == TypeUtils._undefined) {
+ String errorMessage = "The invocation prefix has no return parameter." ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ // If the of prefix is of multiplicity 1 and if it has an operation toSequence (i.e., it is a collection class)
+ // Then, depending on the kind of suffix, it may be necessary to propagate a sequence has the prefix type
+ if (typeOfPrefix.getMultiplicity().getUpperBound() == 1 &&
+ (exp instanceof SequenceOperationExpression ||
+ exp instanceof SelectOrRejectOperation
+ // || exp.getSuffix() instanceof ... TODO
+ )) {
+ Classifier actualPrefixType = typeOfPrefix.getTypeFacade().extractActualType() ;
+ if( actualPrefixType != null) {
+ Operation toSequenceOperation = null ;
+ for (int i = 0 ; i<actualPrefixType.getAllOperations().size() && toSequenceOperation == null ; i++) {
+ Operation o = actualPrefixType.getAllOperations().get(i) ;
+ if (o.getName().equals("toSequence"))
+ toSequenceOperation = o ;
+ }
+ if (toSequenceOperation != null) {
+ typeOfPrefix = TypeExpressionFactory.eInstance.createTypeExpression(toSequenceOperation.getReturnResult()) ;
+ }
+ }
+ }
+
+ if (exp instanceof ClassExtentExpression) {
+ // TODO
+ String errorMessage = "Class extent expressions are not supported in this version of the Alf editor" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ else if (exp instanceof LinkOperationExpression) {
+ // TODO
+ String errorMessage = "Link operation expressions are not supported in this version of the Alf editor" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ else if (exp instanceof OperationCallExpression) {
+ return getTypeOfOperationCallExpression((OperationCallExpression)exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof PropertyCallExpression) {
+ return getTypeOfPropertyCallExpression((PropertyCallExpression)exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceExpansionExpression) {
+ return getTypeOfSequenceExpansionExpression((SequenceExpansionExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceOperationExpression) {
+ return getTypeOfSequenceOperationExpression((SequenceOperationExpression)exp, typeOfPrefix) ;
+ }
+ else {// exp instanceof SequenceReductionExpression
+ return getTypeOfSequenceReductionExpression((SequenceReductionExpression) exp, typeOfPrefix) ;
+ }
+ }
+
+ public TypeExpression getTypeOfSequenceOperationExpression(SequenceOperationExpression exp, TypeExpression typeOfPrefix) {
+
+ if (exp.getOperationName() == null) {
+ String errorMessage = "Sequence function is missing" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceOperationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ // first tries to resolve the behavior name
+ SignatureFacade s = null ;
+ TypeFacade cddBehaviorFacade = TypeFacadeFactory.eInstance.createVoidFacade(exp.getOperationName()) ;
+ if (cddBehaviorFacade instanceof ErrorTypeFacade) {
+ // the behavior has not been found using default strategies.
+ // Tries to find it in predefined collection functions
+ s = TypeUtils.predefinedCollectionFunctions.get(exp.getOperationName().getId()) ;
+ if (s == null) {
+ return TypeExpressionFactory.eInstance.createTypeExpression(cddBehaviorFacade) ;
+// EObject source = exp.eContainer() ;
+// EStructuralFeature containingFeature = exp.eContainingFeature() ;
+// String errorMessage = "Could not resolve collection function " + exp.getOperationName().getId() ;
+// ErrorTypeFacade unsupportedCase =
+// TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containingFeature) ;
+// return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ }
+ else {
+ Classifier cddBehavior = cddBehaviorFacade.extractActualType() ;
+ if (! (cddBehavior instanceof Behavior)) {
+ String errorMessage = cddBehavior.getName() + " does not resolve to a Behavior" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceOperationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ else {
+ s = SignatureFacadeFactory.eInstance.createSignatureFacade(cddBehavior) ;
+ }
+ }
+
+ if (s.isATemplate()) {
+ // A binding needs to be done, with the type of the prefix as an actual.
+ Map<TemplateParameter, ParameterableElement> substitutions = new HashMap<TemplateParameter, ParameterableElement>() ;
+ for (TemplateParameter tp : ((TemplateableElement)s.getActualSignatureObject()).getOwnedTemplateSignature().getOwnedParameters()) {
+ substitutions.put(tp,typeOfPrefix.getTypeFacade().extractActualType()) ;
+ }
+ String sLabelInCaseOfErrorInBinding = "" + s.getLabel() ;
+ s = s.bindTemplate(substitutions) ;
+ if (s == null) { // a problem occurred with binding
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Could not implicitly bind behavior " + sLabelInCaseOfErrorInBinding + " with actual parameter " + typeOfPrefix.getTypeFacade().getLabel() ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ }
+
+ // The signature has been resolved.
+ // Needs to determine if this is a valid signature. i.e. must have its first parameter with direction in or inout, and multiplicity *
+ if (s.getParameters().isEmpty()) {
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Invalid sequence function. Should at least one in or inout parameter with multiplicity *" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ Behavior sequenceFunction = (Behavior)s.getActualSignatureObject() ;
+ Parameter firstParameter = sequenceFunction.getOwnedParameters().get(0) ;
+ if (((firstParameter.getDirection()!= ParameterDirectionKind.IN_LITERAL) && (firstParameter.getDirection() != ParameterDirectionKind.INOUT_LITERAL)) ||
+ firstParameter.getUpper() != -1) {
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Invalid sequence function. The first parameter should have direction in or inout, with multiplicity *" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+ // Then determines if arguments match parameters of the signature
+ List<TypeExpression> arguments = new ArrayList<TypeExpression>() ;
+ arguments.add(typeOfPrefix) ;
+ for (TupleElement e : exp.getTuple().getTupleElements()) {
+ TypeExpression argType = getTypeOfExpression(e.getArgument()) ;
+ if (argType.getTypeFacade() != null && argType.getTypeFacade() instanceof ErrorTypeFacade)
+ return argType ;
+ arguments.add(argType) ;
+ }
+ String argumentsAreCompatible = s.isCompatibleWithMe(arguments, true) ;
+ if (! (argumentsAreCompatible.length() == 0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ argumentsAreCompatible,
+ exp,
+ AlfPackage.eINSTANCE.getSequenceOperationExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ TypeExpression typeOfSuffix = s.getReturnType() ;
+
+ if (exp.getSuffix() != null) {
+ return this.getTypeOfSuffixExpression(exp.getSuffix(), typeOfSuffix) ;
+ }
+
+ return typeOfSuffix ;
+ }
+
+ public TypeExpression getTypeOfSequenceReductionExpression(SequenceReductionExpression exp, TypeExpression typeOfPrefix) {
+ int upperBoundOfPrefix = typeOfPrefix.getMultiplicityFacade().getUpperBound() ;
+ // first check if the prefix is a collection
+ if (!(upperBoundOfPrefix > 1) && upperBoundOfPrefix != -1) {
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ String errorMessage = "Prefix must be a collection" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ if (exp.getBehavior() == null) {
+ String errorMessage = "Reduction behavior is missing" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceReductionExpression_Behavior()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ // first tries to resolve the behavior name
+ TypeFacade cddBehaviorFacade = TypeFacadeFactory.eInstance.createVoidFacade(exp.getBehavior()) ;
+ if (cddBehaviorFacade instanceof ErrorTypeFacade)
+ return TypeExpressionFactory.eInstance.createTypeExpression(cddBehaviorFacade) ;
+
+ Classifier cddBehavior = cddBehaviorFacade.extractActualType() ;
+ if (! (cddBehavior instanceof Behavior)) {
+ String errorMessage = cddBehavior.getName() + " does not resolve to a Behavior" ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceReductionExpression_Behavior()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ Behavior behavior = (Behavior)cddBehavior ;
+ // check that the behavior is a valid reduction behavior
+ // i.e., it has exactly two in parameters and one return parameter, all with multiplicity 1
+ int n_inputParameters = 0 ;
+ boolean invalidReductionBehavior = false ;
+ boolean returnParameterFound = false ;
+ Classifier paramsType = null ;
+ for (int i = 0 ; i < behavior.getOwnedParameters().size() && !invalidReductionBehavior ; i++) {
+ Parameter p = behavior.getOwnedParameters().get(i) ;
+ switch (p.getDirection()) {
+ case IN_LITERAL:
+ n_inputParameters++ ;
+ if (n_inputParameters > 2) {
+ invalidReductionBehavior = true ;
+ break ;
+ }
+ if (p.getLower() != 1 || p.getUpper() != 1) {
+ invalidReductionBehavior = true ;
+ break ;
+ }
+ if (paramsType == null) {
+ paramsType = (Classifier)p.getType() ;
+ if (paramsType == null) invalidReductionBehavior = true ;
+ }
+ else {
+ if (paramsType != ((Classifier)p.getType()))
+ invalidReductionBehavior = true ;
+ }
+ break;
+ case INOUT_LITERAL:
+ invalidReductionBehavior = true ;
+ break;
+ case OUT_LITERAL:
+ invalidReductionBehavior = true ;
+ break;
+ case RETURN_LITERAL:
+ returnParameterFound = true ;
+ if (p.getLower() != 1 || p.getUpper() != 1) {
+ invalidReductionBehavior = true ;
+ break ;
+ }
+ if (paramsType == null) {
+ paramsType = (Classifier)p.getType() ;
+ if (paramsType == null) invalidReductionBehavior = true ;
+ }
+ else {
+ if (paramsType != ((Classifier)p.getType()))
+ invalidReductionBehavior = true ;
+ }
+ break;
+ }
+ }
+ SignatureFacade behaviorFacade = SignatureFacadeFactory.eInstance.createSignatureFacade(behavior) ;
+ if (! (!invalidReductionBehavior && returnParameterFound)) {
+ String errorMessage = behaviorFacade.getLabel() + " is not a valid reduction behavior. It should have exactly two in parameters, one return parameter, all with multiplicity [1..1], and all with the same type." ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceReductionExpression_Behavior()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ // The signature is valid. Finally needs to determine if the type of the elements in the collection is compatible with the type of the parameters
+ if (TypeFacadeFactory.eInstance.createTypeFacade(paramsType).isCompatibleWithMe(typeOfPrefix.getTypeFacade()) == 0) {
+ String errorMessage = behaviorFacade.getLabel() + " does not apply to arguments of type " + typeOfPrefix.getTypeFacade().getLabel() ;
+ ErrorTypeFacade unsupportedCase =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getSequenceReductionExpression_Behavior()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(unsupportedCase) ;
+ }
+
+ TypeExpression typeOfExpression = TypeExpressionFactory.eInstance.createTypeExpression(typeOfPrefix.getTypeFacade()) ;
+
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfExpression) ;
+ return typeOfExpression ;
+ }
+
+ public TypeExpression getTypeOfSequenceExpansionExpression(SequenceExpansionExpression exp, TypeExpression typeOfPrefix) {
+ if (exp instanceof SelectOrRejectOperation) {
+ return getTypeOfSelectOrRejectOperation((SelectOrRejectOperation)exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof CollectOrIterateOperation) {
+ return getTypeOfCollectOrIterateOperation((CollectOrIterateOperation)exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof ForAllOrExistsOrOneOperation) {
+ return getTypeOfForAllOrExistsOrOneOperation((ForAllOrExistsOrOneOperation)exp, typeOfPrefix) ;
+ }
+ else { // exp instanceof IsUniqueOperation
+ return getTypeOfIsUniqueOperation((IsUniqueOperation)exp, typeOfPrefix) ;
+ }
+ }
+
+ private TypeExpression getTypeOfIsUniqueOperation(IsUniqueOperation exp, TypeExpression typeOfPrefix) {
+ if (exp.getName() == null) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local variable definition is missing",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ // first check that the local variable name is not already used
+ if (! AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(exp.eContainer()).resolveByName(exp.getName()).isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local name " + exp.getName() + " is not available",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfCondition = getTypeOfExpression(exp.getExpr()) ;
+ if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfCondition ;
+
+ int upperBound = typeOfCondition.getMultiplicity().getUpperBound() ;
+
+ if (upperBound == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Expression must be typed",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Expr()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfExpression = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean) ;
+
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfExpression) ;
+
+ return typeOfExpression ;
+ }
+
+ private TypeExpression getTypeOfForAllOrExistsOrOneOperation(ForAllOrExistsOrOneOperation exp, TypeExpression typeOfPrefix) {
+ if (exp.getName() == null) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local variable definition is missing",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ // first check that the local variable name is not already used
+ if (! AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(exp.eContainer()).resolveByName(exp.getName()).isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local name " + exp.getName() + " is not available",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfCondition = getTypeOfExpression(exp.getExpr()) ;
+ if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfCondition ;
+
+ if (TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean).isCompatibleWithMe(typeOfCondition) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Expecting an expression of type Boolean. Found an expression of type " + typeOfCondition.getLabel(),
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Expr()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfExpression = TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean) ;
+
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfExpression) ;
+
+ return typeOfExpression ;
+ }
+
+ private TypeExpression getTypeOfCollectOrIterateOperation(CollectOrIterateOperation exp, TypeExpression typeOfPrefix) {
+ if (exp.getName() == null) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local variable definition is missing",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ // first check that the local variable name is not already used
+ if (! AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(exp.eContainer()).resolveByName(exp.getName()).isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local name " + exp.getName() + " is not available",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfCondition = getTypeOfExpression(exp.getExpr()) ;
+ if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfCondition ;
+
+ int lowerBound = typeOfPrefix.getMultiplicity().getLowerBound() * typeOfCondition.getMultiplicity().getLowerBound() ;
+ int upperBound = typeOfPrefix.getMultiplicity().getUpperBound() * typeOfCondition.getMultiplicity().getUpperBound() ;
+ lowerBound = lowerBound < 0 ? -1 : lowerBound ;
+ upperBound = upperBound < 0 ? -1 : upperBound ;
+
+ if (upperBound == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Expression must be typed",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Expr()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfExpression = TypeExpressionFactory.eInstance.createTypeExpression(typeOfCondition.getTypeFacade()) ;
+ typeOfExpression.setMultiplicity(
+ MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(
+ lowerBound, // Lower bound
+ upperBound, // Upper bound
+ typeOfPrefix.getMultiplicity().isUnique(), // is unique
+ typeOfPrefix.getMultiplicity().isOrdered())) ; // is ordered
+
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfExpression) ;
+
+ return typeOfExpression ;
+ }
+
+ private TypeExpression getTypeOfSelectOrRejectOperation(SelectOrRejectOperation exp, TypeExpression typeOfPrefix) {
+ if (exp.getName() == null) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local variable definition is missing",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ // first check that the local variable name is not already used
+ if (! AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(exp.eContainer()).resolveByName(exp.getName()).isEmpty()) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Local name " + exp.getName() + " is not available",
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Name()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfCondition = getTypeOfExpression(exp.getExpr()) ;
+ if (typeOfCondition.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfCondition ;
+
+ if (TypeExpressionFactory.eInstance.createTypeExpression(TypeUtils._boolean).isCompatibleWithMe(typeOfCondition) == 0) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ "Expecting an expression of type Boolean. Found an expression of type " + typeOfCondition.getLabel(),
+ exp,
+ AlfPackage.eINSTANCE.getSequenceExpansionExpression_Expr()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ TypeExpression typeOfExpression = TypeExpressionFactory.eInstance.createTypeExpression(typeOfPrefix.getTypeFacade()) ;
+ typeOfExpression.setMultiplicity(
+ MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(
+ 0, // Lower bound
+ typeOfPrefix.getMultiplicity().getUpperBound(), // Upper bound
+ typeOfPrefix.getMultiplicity().isUnique(), // is unique
+ typeOfPrefix.getMultiplicity().isOrdered())) ; // is ordered
+
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfExpression) ;
+
+ return typeOfExpression ;
+ }
+
+ public TypeExpression getTypeOfPropertyCallExpression(PropertyCallExpression exp, TypeExpression typeOfPrefix) {
+ Classifier type = typeOfPrefix.getTypeFacade().extractActualType() ;
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containtFeature = exp.eContainingFeature() ;
+ if (type == null) {
+ String errorMessage = "Type of prefix is \"any\". Could not validate suffix." ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+
+ List<EObject> matchingProperties = AlfScopeProvider.scopingTool.getVisibleVariablesOrParametersOrProperties(type).resolveByName(exp.getPropertyName()) ;
+ if (matchingProperties.size() == 0) {
+ String errorMessage = "Could not resolve property " + exp.getPropertyName() + " for classifier " + type.getName() ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else if (matchingProperties.size() > 1) {
+ String errorMessage = exp.getPropertyName() + " matches multiple properties. Classifier " + type.getName() + " is illformed. Duplicate properties should be renamed or deleted.";
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else { // exactly one property is matched
+ int upperBoundOfPrefix = typeOfPrefix.getMultiplicityFacade().getUpperBound() ;
+ if (upperBoundOfPrefix == -1 || upperBoundOfPrefix > 1) {
+ String errorMessage = "The prefix of this property call is a collection. An index should be used to access property " + exp.getPropertyName() ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ TypeExpression typeOfSuffix = TypeExpressionFactory.eInstance.createTypeExpression(matchingProperties.get(0)) ;
+ // Before building the type of this suffix, needs to check if there is a valid index
+ if (exp.getIndex() != null) {
+ if (typeOfSuffix.isACollection()) {
+ // TODO needs to validate the index
+ TypeExpression typeOfIndex = getTypeOfExpression(exp.getIndex()) ;
+ if (typeOfIndex.getTypeFacade() instanceof ErrorTypeFacade) {
+ return typeOfIndex ;
+ }
+ else if (typeOfIndex.isACollection() || typeOfIndex.getTypeFacade() != TypeUtils._integer) {
+ String errorMessage = "Expecting an expression of type Integer. Found an expression of type " + typeOfIndex.getLabel() ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, AlfPackage.eINSTANCE.getPropertyCallExpression_Index()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else if (! typeOfSuffix.isOrdered()) {
+ String errorMessage = "Unexpected index. " + exp.getPropertyName() + " is not ordered." ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ typeOfSuffix = TypeExpressionFactory.eInstance.createTypeExpression(typeOfSuffix.getTypeFacade()) ;
+ }
+ }
+ else {
+ String errorMessage = "Unexpected index. " + exp.getPropertyName() + " is not a collection." ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containtFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfSuffix) ;
+ else
+ return typeOfSuffix ;
+ }
+ }
+ }
+
+ public TypeExpression getTypeOfOperationCallExpression(OperationCallExpression exp, TypeExpression typeOfPrefix) {
+ Classifier type = typeOfPrefix.getTypeFacade().extractActualType() ;
+ EObject source = exp.eContainer() ;
+ EStructuralFeature containingFeature = exp.eContainingFeature() ;
+ if (type == null) {
+ String errorMessage = "Type of prefix is \"any\". Could not validate suffix." ;
+ ErrorTypeFacade error =
+ TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containingFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ List<TypeExpression> arguments = new ArrayList<TypeExpression>() ;
+ for (TupleElement e : exp.getTuple().getTupleElements()) {
+ TypeExpression argType = getTypeOfExpression(e.getArgument()) ;
+ if (argType.getTypeFacade() != null && argType.getTypeFacade() instanceof ErrorTypeFacade)
+ return argType ;
+ arguments.add(argType) ;
+ }
+ List<EObject> matchingOperations = AlfScopeProvider.scopingTool.getVisibleOperationsOrBehaviors(type).resolveByName(exp.getOperationName()) ;
+ TypeExpression typeOfSuffix ;
+ if (matchingOperations.size() == 0) {
+ String errorMessage = "" ;
+ ErrorTypeFacade error = null ;
+ if (exp.getOperationName().equals("destroy")) {// This is the case of the default destructor
+ if (typeOfPrefix.getTypeFacade().extractActualType() instanceof PrimitiveType)
+ errorMessage += "Primitive types do not have destructors." ;
+ else if (arguments.size() > 0)
+ errorMessage += "Default destructor has not parameters" ;
+ if (! (errorMessage.length() == 0)) {
+ error = TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containingFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ return TypeExpressionFactory.eInstance.createTypeExpression(_undefined) ;
+ }
+ errorMessage = "Could not resolve operation " + exp.getOperationName() + " for classifier " + type.getName() ;
+ error = TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, source, containingFeature) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else if (matchingOperations.size() > 1) {
+ List<SignatureFacade> availableSignatures = new ArrayList<SignatureFacade>() ;
+ for (EObject operation : matchingOperations) {
+ availableSignatures.add(SignatureFacadeFactory.eInstance.createSignatureFacade(operation)) ;
+ }
+ List<SignatureFacade> selectedSignatures = SignatureFacade.findNearestSignature(arguments, availableSignatures) ;
+ if (selectedSignatures.size() > 1) { // could not infer the actual operations even with type of arguments
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ exp.getOperationName() + " resolves to multiple elements",
+ exp,
+ AlfPackage.eINSTANCE.getOperationCallExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ else if (selectedSignatures.size() == 0) {
+ String errorMessage = exp.getOperationName() + " does not apply to arguments (" ;
+ boolean first = true ;
+ for (TypeExpression argType : arguments) {
+ if (!first)
+ errorMessage += ", " ;
+ else
+ first = false ;
+ errorMessage += argType.getLabel() ;
+ }
+ errorMessage += ")" ;
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ errorMessage,
+ exp,
+ AlfPackage.eINSTANCE.getOperationCallExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ SignatureFacade operationSignature = selectedSignatures.get(0) ;
+ String argumentsAreCompatible = operationSignature.isCompatibleWithMe(arguments, true) ;
+ if (! (argumentsAreCompatible.length() == 0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ argumentsAreCompatible,
+ exp,
+ AlfPackage.eINSTANCE.getOperationCallExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ typeOfSuffix = selectedSignatures.get(0).getReturnType() ;
+ }
+ }
+ else { // exactly one operation is matched
+ typeOfSuffix = TypeExpressionFactory.eInstance.createTypeExpression(matchingOperations.get(0)) ;
+ SignatureFacade operationSignature = new SignatureFacade(matchingOperations.get(0)) ;
+ String argumentsAreCompatible = operationSignature.isCompatibleWithMe(arguments, true) ;
+ if (! (argumentsAreCompatible.length() == 0)) {
+ ErrorTypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(
+ argumentsAreCompatible,
+ exp,
+ AlfPackage.eINSTANCE.getOperationCallExpression_OperationName()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error);
+ }
+ typeOfSuffix = operationSignature.getReturnType() ;
+ }
+ if (exp.getSuffix() != null && exp.getSuffix() != suffixToBeIgnored)
+ return getTypeOfSuffixExpression(exp.getSuffix(), typeOfSuffix) ;
+ else
+ return typeOfSuffix ;
+ }
+
+ public TypeExpression getTypeOfSequenceElement (SequenceElement s) {
+ if (s instanceof Expression)
+ return getTypeOfExpression((Expression)s) ;
+ else // instanceof SequenceConstructionExpression
+ return getTypeOfSequenceConstructionExpression((SequenceConstructionExpression)s) ;
+ }
+
+ public TypeExpression getTypeOfSequenceConstructionExpression (SequenceConstructionExpression s) {
+ String errorMessage = "";
+ ErrorTypeFacade error = null ;
+ if (s.getSequenceElement() == null || s.getSequenceElement().isEmpty()) {
+ errorMessage = "Invalid sequence construction expression." ;
+ error = TypeFacadeFactory.eInstance
+ .createErrorTypeFacade(errorMessage, s, AlfPackage.eINSTANCE.getSequenceConstructionExpression_SequenceElement()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ TypeExpression baseType = this.getTypeOfSequenceElement(s.getSequenceElement().get(0)) ;
+ if (baseType.getTypeFacade() instanceof ErrorTypeFacade)
+ return baseType ;
+ if (s.getRangeUpper() != null) { // Sequence is specified as a range
+ TypeExpression upperType = this.getTypeOfExpression(s.getRangeUpper()) ;
+ if (upperType.getTypeFacade() instanceof ErrorTypeFacade)
+ return upperType ;
+ if (upperType.isCompatibleWithMe(baseType) != 0)
+ return TypeExpressionFactory.eInstance.createTypeExpression(upperType.getTypeFacade(), 0, -1, false, true) ;
+ else if (baseType.isCompatibleWithMe(upperType) != 0)
+ return TypeExpressionFactory.eInstance.createTypeExpression(baseType.getTypeFacade(), 0, -1, false, true) ;
+ else {
+ errorMessage += "All the elements in the sequence must be type compatible." ;
+ error = TypeFacadeFactory.eInstance
+ .createErrorTypeFacade(errorMessage, s, AlfPackage.eINSTANCE.getSequenceConstructionExpression_SequenceElement()) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ }
+ else {// Values contained in the sequence are enumerated
+ List<TypeExpression> typeOfSequenceElements = new ArrayList<TypeExpression>() ;
+ typeOfSequenceElements.add(baseType) ;
+ for (int i = 1 ; i < s.getSequenceElement().size() ; i ++) {
+ TypeExpression t = this.getTypeOfSequenceElement(s.getSequenceElement().get(i)) ;
+ if (t.getTypeFacade() instanceof ErrorTypeFacade)
+ return t ;
+ else
+ typeOfSequenceElements.add(t) ;
+ }
+ TypeExpression commonSuperType = this.findCommonSuperType(typeOfSequenceElements) ;
+ if (commonSuperType == null) {
+ errorMessage = "All the elements in the sequence must be type compatible." ;
+ error = TypeFacadeFactory.eInstance
+ .createErrorTypeFacade(errorMessage, s, AlfPackage.eINSTANCE.getSequenceConstructionExpression_SequenceElement()) ;
+ commonSuperType = TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+ else {
+ commonSuperType.setMultiplicity(MultiplicityFacadeFactory.eInstance.createMultiplicityFacade(-1)) ;
+ }
+ return commonSuperType ;
+ }
+ }
+
+ private TypeExpression findCommonSuperType(List<TypeExpression> l) {
+ TypeExpression mostGeneral = l.get(0) ;
+ for (int i = 1 ; i < l.size() && mostGeneral != null ; i ++) {
+ TypeExpression current = l.get(i) ;
+ if (mostGeneral == current)
+ ;
+ else if (current.isCompatibleWithMe(mostGeneral) != 0)
+ ;
+ else if (mostGeneral.isCompatibleWithMe(current) != 0)
+ mostGeneral = current ;
+ else
+ mostGeneral = null ;
+ }
+ return mostGeneral ;
+ }
+
+ public TypeExpression getTypeOfCandidateExpression(EObject exp) {
+ // EObject cddExpression = o ;
+ if (exp instanceof Tuple)
+ return getTypeOfCandidateExpression(exp.eContainer()) ;
+ else if (exp instanceof Expression)
+ return getTypeOfExpression((Expression) exp) ;
+ else if (exp instanceof ConditionalTestExpression)
+ return getTypeOfConditionalTestExpression((ConditionalTestExpression)exp) ;
+ else if (exp instanceof ConditionalOrExpression)
+ return getTypeOfConditionalOrExpression((ConditionalOrExpression) exp) ;
+ else if (exp instanceof ConditionalAndExpression)
+ return getTypeOfConditionalAndExpression((ConditionalAndExpression) exp) ;
+ else if (exp instanceof InclusiveOrExpression)
+ return getTypeOfInclusiveOrExpression((InclusiveOrExpression) exp) ;
+ else if (exp instanceof ExclusiveOrExpression)
+ return getTypeOfExclusiveOrExpression((ExclusiveOrExpression) exp) ;
+ else if (exp instanceof AndExpression)
+ return getTypeOfAndExpression((AndExpression) exp) ;
+ else if (exp instanceof EqualityExpression)
+ return getTypeOfEqualityExpression((EqualityExpression) exp) ;
+ else if (exp instanceof ClassificationExpression)
+ return getTypeOfClassificationExpression((ClassificationExpression) exp) ;
+ else if (exp instanceof RelationalExpression)
+ return getTypeOfRelationalExpression((RelationalExpression) exp) ;
+ else if (exp instanceof ShiftExpression)
+ return getTypeOfShiftExpression((ShiftExpression) exp) ;
+ else if (exp instanceof AdditiveExpression)
+ return getTypeOfAdditiveExpression((AdditiveExpression) exp) ;
+ else if (exp instanceof MultiplicativeExpression)
+ return getTypeOfMultiplicativeExpression((MultiplicativeExpression) exp) ;
+ else if (exp instanceof UnaryExpression)
+ return getTypeOfUnaryExpression((UnaryExpression) exp) ;
+ else if (exp instanceof PrimaryExpression)
+ return getTypeOfPrimaryExpression((PrimaryExpression) exp) ;
+ else if (exp instanceof ValueSpecification)
+ return getTypeOfValueSpecification((ValueSpecification)exp) ;
+ else if (exp instanceof NullExpression)
+ return getTypeOfNullExpression((NullExpression) exp) ;
+ else if (exp instanceof InstanceCreationExpression)
+ return getTypeOfInstanceCreationExpression((InstanceCreationExpression) exp) ;
+ else if (exp instanceof SuperInvocationExpression)
+ return getTypeOfSuperInvocationExpression((SuperInvocationExpression) exp) ;
+ else if (exp instanceof NonLiteralValueSpecification)
+ return getTypeOfNonLiteralValueSpecification((NonLiteralValueSpecification) exp) ;
+ else if (exp instanceof LITERAL)
+ return getTypeOfLITERAL((LITERAL) exp) ;
+ else if (exp instanceof ParenthesizedExpression)
+ return getTypeOfParenthesizedExpression((ParenthesizedExpression) exp) ;
+ else if (exp instanceof NameExpression)
+ return getTypeOfNameExpression((NameExpression) exp) ;
+ else if (exp instanceof ThisExpression)
+ return getTypeOfThisExpression((ThisExpression) exp) ;
+ else if (exp instanceof SequenceOperationExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSequenceOperationExpression((SequenceOperationExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceReductionExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSequenceReductionExpression((SequenceReductionExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceExpansionExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSequenceExpansionExpression((SequenceExpansionExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof IsUniqueOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfIsUniqueOperation((IsUniqueOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof ForAllOrExistsOrOneOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfForAllOrExistsOrOneOperation((ForAllOrExistsOrOneOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof CollectOrIterateOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfCollectOrIterateOperation((CollectOrIterateOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SelectOrRejectOperation) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfSelectOrRejectOperation((SelectOrRejectOperation) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof PropertyCallExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfPropertyCallExpression((PropertyCallExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof OperationCallExpression) {
+ // This is a suffix expression
+ // First determine type of prefix.
+ TypeUtils localTypeUtil = new TypeUtils((SuffixExpression)exp) ;
+ TypeExpression typeOfPrefix = localTypeUtil.getTypeOfCandidateExpression(exp.eContainer()) ;
+ if (typeOfPrefix.getTypeFacade() instanceof ErrorTypeFacade)
+ return typeOfPrefix ;
+ return getTypeOfOperationCallExpression((OperationCallExpression) exp, typeOfPrefix) ;
+ }
+ else if (exp instanceof SequenceElement)
+ return getTypeOfSequenceElement ((SequenceElement) exp) ;
+ else if (exp instanceof SequenceConstructionExpression)
+ return getTypeOfSequenceConstructionExpression ((SequenceConstructionExpression) exp) ;
+
+ String errorMessage = "Not an expression." ;
+ TypeFacade error = TypeFacadeFactory.eInstance.createErrorTypeFacade(errorMessage, exp, null) ;
+ return TypeExpressionFactory.eInstance.createTypeExpression(error) ;
+ }
+}
+
diff --git a/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/VoidFacade.java b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/VoidFacade.java new file mode 100644 index 00000000000..c3e5613a44a --- /dev/null +++ b/extraplugins/alf09/src/org/eclipse/papyrus/alf/validation/typing/VoidFacade.java @@ -0,0 +1,34 @@ +/*****************************************************************************
+ * Copyright (c) 2011 CEA LIST.
+ *
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.alf.validation.typing;
+
+
+public class VoidFacade extends TypeFacade {
+
+ private TypeFacade typeFacade ;
+
+ public VoidFacade(TypeFacade typeFacade) {
+ this.typeFacade = typeFacade ;
+ this.typeObject = typeFacade.typeObject ;
+ }
+
+ public TypeFacade getTypeFacade() {
+ return typeFacade ;
+ }
+
+ @Override
+ public String getLabel() {
+ return typeFacade != null ? typeFacade.getLabel() : "" ;
+ }
+}
|