Esempio n. 1
0
 def sourceImport(self, id, optional=True):
     #type: (Text) -> Optional[SourceImport]
     """
     Return "the one and only one" sourceImport for a
     given metamodel id.
     If there is no sourceImport then add an issue,
     unless optional is True in which case None is returned.
     If there is more than one sourceImport then an issue
     is added.
     """
     from modelscripts.megamodels import Megamodel
     metamodel_label = Megamodel.theMetamodel(id=id).label
     if id not in self._importsByMetamodelId:
         if optional:
             return None
         else:
             Issue(
                 origin=self.modelSource,
                 level=Levels.Fatal,
                 message=
                     'No %s model imported.' % metamodel_label )
     r=self._importsByMetamodelId[id]
     if len(r)==1:
         return r[0]
     else:
         Issue(
             origin=self.modelSource,
             level=Levels.Fatal,
             message=
                 'More than on %s model imported.' % metamodel_label)
Esempio n. 2
0
 def sourceMetamodel(self):
     #type: (MetamodelDependency) -> Metamodel
     """
     Source metamodel ot ValueError if this metamodel
     is not registered yet (which should not happen).
     """
     try:
         from modelscripts.megamodels import Megamodel
         return Megamodel.theMetamodel(id=self.sourceId)
     except:
         raise ValueError(
             'No target "%s" metamodel registered from %s' % (
                 self.sourceId,
                 self.targetId
             ))
Esempio n. 3
0
def _matchModelDefinition(
        lineNo,
        modelSourceFile,
        justMatch=False,
        # prefixRegexp=r' *(--)? *@?',
        noSymbolChecking=False,
        recognizeUSEOCLNativeModelDefinition=False):
    # type: (int, ModelSourceFile, bool, bool, bool) -> Optional[Union[bool,DefinitionStatement]]
    """
        Check if the line is a model definition statement.

        If justMatch just indicates if the line is recognized.
        In that case it returns True otherwise None.

        If not justMatch build an ImportStatement (if possible)
        Return None if this is not the case.
        Return a ModelDefinitionStatement if the stmt is valid.
        Otherwise raise a value error.
        Definition statements looks like this
            preliminary usecase model MyModel
            class model MyModel

        If 'recognizeUSEOCLNativeModelDefinition' then the line
        "model <NAME>" is accepted as the model definition in USE OCL
        files. This is a patch good enough for now for .use file.
        Later the .use file could be generated and the syntax improved.
    """
    def _parseStandardSyntax():
        re_stmt = (r'^ *((?P<modelKind>\w+) +)?' + r'(?P<metamodelLabel>\w+)' +
                   r' +model' + r' +(?P<name>\w+) *$')
        line = modelSourceFile.realSourceLines[lineNo - 1]
        m = re.match(re_stmt, line, re.MULTILINE)
        if m is None:
            return None
        else:
            if m.group('modelKind') == 'import':  # because overlapping regexp
                return None
            if justMatch:
                return True
            else:
                return {
                    'modelKind': m.group('modelKind'),
                    'metamodelLabel': m.group('metamodelLabel'),
                    'name': m.group('name')
                }

    def _parseUSEOCLSyntax():
        re_stmt = ('^' + r' *model' + r' +(?P<name>\w+) *$')
        line = modelSourceFile.realSourceLines[lineNo - 1]
        m = re.match(re_stmt, line, re.MULTILINE)
        if m is None:
            return None
        if justMatch:
            return True
        else:
            return {
                'modelKind': '',
                'metamodelLabel': 'class',
                'name': m.group('name')
            }

    def _parse():
        r1 = _parseStandardSyntax()
        if r1 is not None or not recognizeUSEOCLNativeModelDefinition:
            return r1
        else:
            # No match so search USEOCL
            return _parseUSEOCLSyntax()

    m = _parse()
    if m in [True, None]:
        return m
    else:
        source_metamodel = modelSourceFile.metamodel

        # get actual metamodel
        metamodel_label = m['metamodelLabel']
        try:
            # could raise ValueError
            from modelscripts.megamodels import Megamodel
            metamodel = Megamodel.theMetamodel(
                label=metamodel_label)  #type: Metamodel
        except ValueError as e:
            LocalizedSourceIssue(
                sourceFile=modelSourceFile,
                line=lineNo,
                level=Levels.Fatal,  # could be error with some work
                message=str(e))

        # check model_kind
        model_kind = ('' if m['modelKind'] is None else m['modelKind'])
        # noinspection PyUnboundLocalVariable
        if model_kind not in metamodel.modelKinds:
            LocalizedSourceIssue(
                sourceFile=modelSourceFile,
                line=lineNo,
                level=Levels.Fatal,  # could be error with some work
                message=(
                    '%s models can\'t be "%s".'
                    ' Choose one of %s.' %
                    (metamodel_label, model_kind, str(metamodel.modelKinds))))

        # Check that the metamodel is the expected one
        # if metamodel != source_metamodel:
        #     LocalizedSourceIssue(
        #         sourceFile=modelSourceFile,
        #         line=lineNo,
        #         level=Levels.Fatal,  # could be error with some work
        #         message=(
        #             'A %s model cannot be defined in a "%s" file.' % (
        #                 metamodel.label,
        #                 source_metamodel.extension,
        #             )))

        # Check name
        name = m['name']
        if not noSymbolChecking and not (Symbol.is_CamlCase(name)):
            LocalizedSourceIssue(
                sourceFile=modelSourceFile,
                line=lineNo,
                level=Levels.Error,
                message=('Invalid model name "%s". It must be in CamlCases.' %
                         (name)))
        if name.lower() != modelSourceFile.name.lower():
            if not recognizeUSEOCLNativeModelDefinition:
                LocalizedSourceIssue(
                    sourceFile=modelSourceFile,
                    line=lineNo,
                    level=Levels.Error,
                    message=(
                        'Model must be named %s according to the name of the file'
                        % (
                            # modelSourceFile.fileName,
                            modelSourceFile.name)))
        return DefinitionStatement(lineNo=lineNo,
                                   sourceFile=modelSourceFile,
                                   modelKind=model_kind,
                                   metamodel=metamodel,
                                   name=name)
Esempio n. 4
0
def _matchModelImport(lineNo, modelSourceFile, justMatch=False):
    #Megamodel statements are always extracted from
    # RAW UNPROCESSED ORIGINAL source file.
    #type: (int, ModelSourceFile, bool) -> Optional[Union[bool,ImportStatement]]
    """
        Check if the line is an import statement.

        If justMatch just indicates if the line is recognized.
        In that case it returns True otherwise None.

        If not justMatch build an ImportStatement (if possible)
        Return None if this is not the case.
        Otherwise return a ModelImportStatement if the import is valid.
        Otherwise raise a fatal error that go in the issue box.
        Import statements looks like this
            import usecase model x.cs
            import glossary model a/b/../c.gls
    """
    re_stmt = (r'^ *(?P<import>import)' + r' +(?P<metamodelLabel>\w+)' +
               r' +model' + r' +from' + r' +\'(?P<target>[\w\./\-]+)\' *$')
    line = modelSourceFile.realSourceLines[lineNo - 1]
    m = re.match(re_stmt, line, re.MULTILINE)

    if m is None:
        return None
    else:
        if justMatch:
            return True
        else:
            source_metamodel = modelSourceFile.metamodel

            # get actual metamodel
            metamodel_label = m.group('metamodelLabel')
            try:
                # could raise ValueError
                from modelscripts.megamodels import Megamodel
                metamodel = Megamodel.theMetamodel(
                    label=metamodel_label)  #type: Metamodel
            except ValueError as e:
                LocalizedSourceIssue(
                    sourceFile=modelSourceFile,
                    line=lineNo,
                    level=Levels.Fatal,  # could be error with some work
                    message=str(e))

            # Check that metamodel dependency is allowed
            target_mms = source_metamodel.outMetamodels
            # noinspection PyUnboundLocalVariable
            if metamodel not in target_mms:
                LocalizedSourceIssue(
                    sourceFile=modelSourceFile,
                    line=lineNo,
                    level=Levels.Fatal,  # could be error with some work
                    message=('A %s model cannot reference a %s model.' %
                             (source_metamodel.label, metamodel.label)))

            # Check path
            literal_target_filename = m.group('target')
            abs_target_filename = os.path.abspath(
                os.path.join(modelSourceFile.directory,
                             literal_target_filename))
            file_extension = os.path.splitext(abs_target_filename)[1]
            if file_extension != metamodel.extension:
                LocalizedSourceIssue(
                    sourceFile=modelSourceFile,
                    line=lineNo,
                    level=Levels.Fatal,  # could be error with some work
                    message=('The extension of the file must be "%s".' %
                             (metamodel.extension)))
            if not os.path.isfile(abs_target_filename):
                LocalizedSourceIssue(
                    sourceFile=modelSourceFile,
                    line=lineNo,
                    level=Levels.Fatal,  # could be error with some work
                    message=('File not found: %s' % literal_target_filename))

            return ImportStatement(
                lineNo=lineNo,
                sourceFile=modelSourceFile,
                metamodel=metamodel,
                absoluteTargetFilename=abs_target_filename,
                literalTargetFileName=literal_target_filename)
Esempio n. 5
0
def scriptsIterator(m2id, expectedIssues):
    metamodel = Megamodel.theMetamodel(id=m2id)
    res = checkFileIssues(metamodel.extension[1:], [metamodel.extension],
                          expectedIssues)
Esempio n. 6
0
sys.path.insert(0, modelscribes_home)
# sys.path.append("/home/jmfavre/.config/gedit")
# sys.path.append("/home/jmfavre/.local/share/gtksourceview-3.0/language-specs")
#------------------------------------------------------

import modelscripts
from modelscripts.megamodels import Megamodel


def source(filename):
    return Megamodel.loadFile(filename)


s = source

M = Megamodel

gl = Megamodel.theMetamodel(id='gl')
cl = Megamodel.theMetamodel(id='cl')
us = Megamodel.theMetamodel(id='us')
ob = Megamodel.theMetamodel(id='ob')
pe = Megamodel.theMetamodel(id='pe')
sc = Megamodel.theMetamodel(id='sc')
mg = Megamodel.theMetamodel(id='mg')

print('ModelScripts Interpreter')
print('========================')
print("source('foo.cls')   to load the file 'foo.cls'")
print('quit()              to quit this session')
print('M                   to get the megamodel')