Ignore:
Timestamp:
10/21/15 02:55:11 (9 years ago)
Author:
Mateusz Poszwa
Message:
  • Updated Xtext-based Framclipse
  • Deleted previous version of Framclipse
Location:
java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScript.xtext

    r437 r440  
    1 grammar com.framsticks.framclipse.FramScript with org.eclipse.xtext.common.Terminals
     1grammar com.framsticks.framclipse.FramScript with org.eclipse.xtext.common.Terminals hidden(SL_COMMENT, ML_COMMENT, WS)
    22
    33import "http://www.eclipse.org/emf/2002/Ecore" as ecore
     
    5454        'prop:'
    5555        headers += PropertyHeader*
    56         'id:' name=ID 
     56        'id:' name=ID
    5757        headers += PropertyHeader+
    5858        ;
    59        
     59
    6060State :
    61         'state:' 
     61        'state:'
    6262        headers += PropertyHeader*
    63         'id:' name=ID 
     63        'id:' name=ID
    6464        headers += PropertyHeader+
    6565        ;
    66        
     66
    6767Include : {Include}
    68         code=Code?
    69         (properties+=Property |
    70         states+=State)*
     68        (
     69                code=Code?
     70                (properties+=Property |
     71                states+=State)*
     72        ) | {Block} statements+=Statement+
    7173;
    72        
     74
    7375Header :
    74         name=ID value=HEADER_VALUE ;
    75        
     76        name=HEADER_ID value=HEADER_VALUE ;
     77
    7678NeuroHeader returns Header :
    7779{IntHeader}             name=('prefinputs:' | 'prefoutput:' | 'preflocation:' | 'vhints:') intValue=IntValue |
     
    7981{IconHeader}    name='icon:~' icon=Icon '~' |
    8082                                Header ;
    81                                
    82 Icon : 
     83
     84Icon :
    8385        INT (',' INT)+ ;
    84        
     86
    8587PropertyHeader returns Header :
    8688        TypeHeader |
    8789        FlagsHeader |
    8890        Header ;
    89        
     91
    9092ShowHeader returns Header :
    91         name='expdef:' value=ID |
     93        name='expdef:' importURI=ID |
    9294        Header ;
    93        
     95
    9496FlagsHeader returns Header :
    9597{IntHeader}     name='flags:' intValue=INT ;
    96        
     98
    9799TypeHeader :
    98         name='type:' type=PropertyType ;
    99        
     100        name=TYPE_HEADER type=PropertyType ;
     101
     102// This terminal is defined separately for use with FramScriptAuxiliaryLexer.
     103terminal TYPE_HEADER : 'type:';
     104
    100105PropertyType :
    101         name=ID (min=Number (max=Number default=Number?)? enums+=ENUM_LITERAL* )? ;
    102        
    103 terminal ENUM_LITERAL :
    104         '~' !('~'|'\r'|'\n')+ ;
    105 
    106 Number :
    107         '-'? (INT | DOUBLE) ;
    108        
     106        name=ID (min=Number max=Number default=(Number|HEADER_VALUE)? enums+=ENUM_LITERAL* )? ;
     107
     108Number : IntNumber | DoubleNumber ;
     109IntNumber : '-'? INT ;
     110DoubleNumber : '-'? DOUBLE ;
     111
    109112CodeSection returns Code :
    110113        'code:~' Code '~' ;
     
    123126IncludeDeclaration :
    124127        '@include' importURI=STRING ;
    125        
     128
     129/*
     130 * For some reason, the '#include' keyword is not matched.
     131 * It is possible it has been overshadowed by SL_COMMENT,
     132 * despite the order in which the two have been defined.
     133 * This has been worked around in FramScriptAuxiliaryLexer.
     134 */
    126135PropertyIncludeDeclaration :
    127         '#include' importURI=STRING ;
    128        
     136        PROP_INCLUDE importURI=STRING ;
     137
     138// keyword separated for use in FramScriptAuxiliaryLexer
     139terminal PROP_INCLUDE : '#include' ;
     140
    129141Block :
    130 {Block} '{' statements+=Statement* '}' ;
    131        
    132 Statement :     
     142        '{' statements+=Statement+ '}' ;
     143
     144Statement :
    133145        ( VariableDeclarationStatement |
    134146        ExpressionStatement |
     
    145157        WhileStatement |
    146158        ForStatement |
     159        ForEachStatement |
    147160{EmptyStatement} ';' ;
    148161
     
    154167       
    155168IfStatement :
    156         'if' '(' condition=Expression ')' if=Statement ('else' else=Statement)? ;
    157        
    158 ForStatement :
    159         'for' '(' init=Assignment? ';' condition=Expression? ';' step=Assignment? ')' body=Statement ;
    160        
     169        'if' '(' condition=Expression ')' if=Statement (=>'else' else=Statement)? ;
     170
     171ForStatement :
     172        'for' '(' (init=Assignment | init=VariableDeclarationStatement)? ';' condition=Expression? ';' step=Assignment? ')' body=Statement ;
     173
     174ForEachStatement :
     175        'for' '(' (decl=Iterator|ref=[VariableDeclaration]) 'in' colection=Expression ')' body=Statement ;
     176
     177Iterator returns VariableDeclaration :
     178        'var' name=ID
     179;
     180
    161181WhileStatement :
    162182        'while' '(' condition=Expression ')' body=Statement ;
     
    182202SwitchStatement :
    183203        'switch' condition=ParExpression '{' labels+=SwitchGroup* '}' ;
    184        
    185 SwitchGroup : 
     204
     205SwitchGroup :
    186206        label=SwitchLabel body=SwitchBlock ;
    187207       
     
    206226
    207227Expression :
    208         UnaryExpression ({Expression.left=current} op=Operator right=Expression)? | 
     228        UnaryExpression ({Expression.left=current} op=Operator right=Expression)? |
    209229        WildcardExpression ;
    210        
    211 UnaryExpression  :
     230
     231UnaryExpression :
    212232        QualifiedExpression2 ({UnaryExpression.arg=current} op = IncrementOperator)? |
    213233        op = (IncrementOperator | UnaryOperator) arg = QualifiedExpression2 |
     234        FunctionLiteral |
    214235        Literal ;
    215        
     236
    216237QualifiedExpression2 returns QualifiedExpression :
    217238        QualifiedExpression |
    218239        (PropertyAccess|StateAccess) ({QualifiedExpression.parent=current}'.' child=QualifiedExpression )? ;
    219        
     240
    220241QualifiedExpression :
    221         ArrayElementExpression ({QualifiedExpression.parent=current}'.' child=QualifiedExpression )? ;
    222        
     242        MemberAccess ({QualifiedExpression.parent=current}'.' child=QualifiedExpression )? ;
     243
     244MemberAccess returns QualifiedExpression:
     245        ArrayElementExpression ( {MemberAccess.left=current} '.[' child=Expression ']')? ;
     246
    223247ArrayElementExpression :
    224248        TerminalExpression ({ArrayElementExpression.array=current} ('[' indexes+=Expression ']')+ )? ;
    225  
     249
    226250TerminalExpression:
     251                                Cast |
     252                                TypeOf |
    227253                                Invocation |
    228254                                Array |
    229                                 Vector |
     255                                Vector |
     256                                Dictionary |
    230257{VariableRef}   var=[VariableDeclaration];
    231                                
     258
     259Cast :
     260        type=('int'|'float'|'string') '(' expression=Expression ')' ;
     261
     262TypeOf :
     263        'typeof' '(' expression=Expression ')' ;
     264
    232265Invocation :
    233266        function=[Function] '(' (args+=Expression (',' args+=Expression)*)? ')' ;
    234        
     267
    235268WildcardExpression :
    236269        value=ID '.*' ;
    237        
     270
    238271PropertyAccess returns QualifiedExpression :
    239         ('Fields.'|'ExpParams.'|'ShowParams.'|'VisParams.') property=[Property] ;
    240        
     272{PropertyAccess}        ('Fields'|'ExpParams'|'ShowParams'|'VisParams') ('.*' | =>('.' property=[Property]) | '.[' (=>property=[Property|STRING] | child=Expression ) ']')? ;
     273
    241274StateAccess returns QualifiedExpression :
    242         'ExpState.' state=[State] ;
    243        
     275{StateAccess}   'ExpState' (".*" | =>('.' state=[State]) | '.[' (=>state=[State|STRING] | child=Expression ) ']')? ;
     276
     277FunctionLiteral:
     278        'function' function=[Function] ;
     279
    244280Literal:
    245 {IntLiteral}    value=IntValue |
    246 {DoubleLiteral} value=DoubleValue |
    247 {StringLiteral} value=STRING |
    248 {HexLiteral}    value=HEX |
     281{IntLiteral}    value=IntValue |
     282{DoubleLiteral} value=DoubleValue |
     283{StringLiteral} value=STRING |
     284{RawStringLiteral}      value=ML_STRING |
     285{HexLiteral}    value=HEX |
    249286{NullLiteral}   'null' ;
    250287
    251288Array :
    252         '[' elements+=Expression (',' elements+=Expression)* ']' ;
     289{Array} '[' (elements+=Expression (',' elements+=Expression)*)? ']' ;
    253290
    254291Vector  :
    255292        '(' elements+=Expression (',' elements+=Expression)* ')' ;
    256293
    257 Operator :
    258         '+' | '-' | '*'| '/' |
     294Dictionary :
     295{Dictionary}    '{' ( keys+=DictKey values+=Expression (',' keys+=DictKey values+=Expression)* )? '}' ;
     296
     297DictKey :
     298        STRING ':' ;
     299
     300Operator :
     301        '+' | '-' | '*'| '/' |
    259302        '&'| '|' | '%' |
    260303        '==' | '!=' | '>=' | '<=' | '<' | '>' |
    261304        '&&' | '||' ;
    262        
     305
    263306UnaryOperator :
    264         '!' | '+' | '-' | 'typeof';
    265        
     307        '!' | '+' | '-';
     308
    266309IncrementOperator :
    267310        '++' | '--' ;
     
    272315DoubleValue hidden() :
    273316        ('+'|'-')? DOUBLE ;
    274        
    275 terminal DOUBLE : 
     317
     318terminal DOUBLE :
    276319        ('0'..'9')*'.'('0'..'9')+ ('e' INT)? |
    277320        INT 'e' INT ;
    278        
    279 terminal HEX :
     321
     322terminal ENUM_LITERAL :
     323        '~' !('~'|'\r'|'\n')+ ;
     324
     325terminal HEX :
    280326        '0x' (('0'..'9')|('a'..'f')|('A'..'F'))+ ;
    281        
    282 terminal HEADER_VALUE :
    283         ':' !('~'|' '|'\t'|'\r'|'\n') !('\n'|'\r')* ('\r'? '\n') |
    284         ':~' -> '~'('\r'? '\n')
    285         ;
    286        
    287 terminal SL_COMMENT : ('//' | '# ')  !('\n'|'\r')* ('\r'? '\n')?;
    288 
     327
     328terminal ML_STRING :
     329        '"""' -> '"""' |
     330        "'''" -> "'''"
     331;
     332
     333terminal SL_COMMENT : ('//' | '#') -> NL ;
     334
     335terminal HEADER_ID :
     336        (
     337                'name' |
     338                'longname' |
     339                'description' |
     340                'group' |
     341                'help' |
     342                'info' |
     343                'neurons'
     344        ) ':'
     345;
     346
     347/*
     348 * This rule should not match anything,
     349 * so expect an error when generating the artifacts.
     350 * If it is not there, something went wrong.
     351 * This rule is here just to make Xtext generate a constant
     352 * to be used in a custom lexer (FramScriptAuriliaryLexer),
     353 * which takes context into account,
     354 * so it is able to recognise HEADER_VALUE
     355 * without conflicting with Framscript code syntax.
     356 * It should match the following rules,
     357 * but only when preceded with HEADER_ID:
     358 *      '~' NL ('\\~'|!'~')* '~' NL | -> NL,
     359 * where NL is defined as: '\r' '\n'? | '\n',
     360 * The final NL is not matched, but it is a part of context.
     361 * This token is also emitted for the default value in PropertyType.
     362 */
     363terminal HEADER_VALUE : 'name:';
     364
     365terminal fragment NL : '\r' '\n'? | '\n' ;
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptRuntimeModule.java

    r437 r440  
    1616import com.framsticks.framclipse.script.context.Framscontext;
    1717import com.framsticks.framclipse.script.model.Framscript;
     18import com.google.inject.Binder;
    1819import com.thoughtworks.xstream.XStream;
    1920
    2021/**
    21  * Use this class to register components to be used within the IDE.
     22 * Use this class to register components to be used at runtime / without the Equinox extension registry.
    2223 */
    2324public class FramScriptRuntimeModule extends com.framsticks.framclipse.AbstractFramScriptRuntimeModule {
     
    5657        }
    5758
     59        @Override
     60        public void configureRuntimeLexer(Binder binder) {
     61                binder.bind(org.eclipse.xtext.parser.antlr.Lexer.class)
     62                        .annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.parser.antlr.LexerBindings.RUNTIME))
     63                        .to(FramScriptAuxiliaryLexer.class);
     64        }
     65
    5866}
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/FramScriptValueConverterService.java

    r438 r440  
    1818                        protected String internalToValue(String s, INode node)
    1919                                        throws ValueConverterException {
    20                                 if (s.startsWith(":~")) {
    21                                         return s.substring(2, s.lastIndexOf('~')).trim();
    22                                 } else {
    23                                         return s.substring(1).trim();
     20                                String r = s;
     21                                if (s.startsWith("~")) {
     22                                        r = s.substring(1, s.lastIndexOf('~'));
    2423                                }
     24                                return r.trim().replaceAll("\\~", "~");
    2525                        }
    2626
    2727                };
    2828        }
    29        
     29
     30        @ValueConverter(rule = "ML_STRING")
     31        public IValueConverter<String> ML_STRING() {
     32
     33                return new AbstractToStringConverter<String>() {
     34
     35                        @Override
     36                        protected String internalToValue(String s, INode node)
     37                                        throws ValueConverterException {
     38                                return s.substring(3, s.length()-3);
     39                        }
     40
     41                };
     42        }
    3043}
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/GenerateFramScript.mwe2

    r438 r440  
    8080                        // Java-based API for validation
    8181                        fragment = validation.JavaValidatorFragment auto-inject {
    82                         //      composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
    83                         //      composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
     82                                composedCheck = "org.eclipse.xtext.validation.ImportUriValidator"
     83                                composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
    8484                        }
    8585
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/formatting/FramScriptFormatter.java

    r437 r440  
    1717
    1818/**
    19  * This class contains custom formatting description.
     19 * This class contains custom formatting declarations.
    2020 *
    21  * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#formatting
    22  * on how and when to use it
     21 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#formatting
     22 * on how and when to use it.
    2323 *
    24  * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an
    25  * example
     24 * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example
    2625 */
    2726public class FramScriptFormatter extends AbstractDeclarativeFormatter {
    28        
    29         @Override
    30         protected FramScriptGrammarAccess getGrammarAccess() {
    31                 return (FramScriptGrammarAccess) super.getGrammarAccess();
    32         }
    33 
    3427        @Override
    3528        protected void configureFormatting(FormattingConfig c) {
    36                 FramScriptGrammarAccess f = getGrammarAccess();
     29                FramScriptGrammarAccess f = (FramScriptGrammarAccess) getGrammarAccess();
    3730               
    3831                //Headers
     
    6861                c.setNoSpace().before(f.getFlagsHeaderAccess().getIntValueAssignment_2());
    6962               
    70                 c.setNoSpace().after(f.getTypeHeaderAccess().getNameTypeKeyword_0_0());
     63                c.setNoSpace().after(f.getTypeHeaderAccess().getNameTYPE_HEADERTerminalRuleCall_0_0());
    7164                c.setLinewrap().after(f.getTypeHeaderAccess().getTypeAssignment_1());
    7265               
     
    9487                // BlockIndentation
    9588                BlockElements block = f.getBlockAccess();
    96                 c.setIndentation(block.getLeftCurlyBracketKeyword_1(),
    97                                 block.getRightCurlyBracketKeyword_3());
    98                 c.setLinewrap().before(block.getLeftCurlyBracketKeyword_1());
    99                 c.setLinewrap().after(block.getLeftCurlyBracketKeyword_1());
    100                 c.setLinewrap().after(block.getRightCurlyBracketKeyword_3());
     89                c.setIndentation(block.getLeftCurlyBracketKeyword_0(),
     90                                block.getRightCurlyBracketKeyword_2());
     91                c.setLinewrap().before(block.getLeftCurlyBracketKeyword_0());
     92                c.setLinewrap().after(block.getLeftCurlyBracketKeyword_0());
     93                c.setLinewrap().after(block.getRightCurlyBracketKeyword_2());
    10194
    10295                // Param
     
    10497                c.setNoLinewrap().around(fullStop);
    10598                c.setNoSpace().around(fullStop);
    106                 c.setNoSpace().after(f.getPropertyAccessAccess().getAlternatives_0());
     99                c.setNoSpace().after(f.getPropertyAccessAccess().getAlternatives_1());
     100                c.setNoSpace().after(f.getPropertyAccessAccess().getAlternatives_2());
    107101               
    108102                // Invocation
     
    117111               
    118112                //Arrays
    119                 c.setNoSpace().after(f.getArrayAccess().getLeftSquareBracketKeyword_0());
     113                c.setNoSpace().after(f.getArrayAccess().getLeftSquareBracketKeyword_1());
    120114                c.setNoSpace().before(f.getArrayAccess().getRightSquareBracketKeyword_3());
    121                 c.setNoSpace().before(f.getArrayAccess().getCommaKeyword_2_0());
     115                c.setNoSpace().before(f.getArrayAccess().getCommaKeyword_2_1_0());
    122116               
    123117                // Unary expression
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/resource/FramScriptResourceDescription.java

    r438 r440  
    1313import com.framsticks.framclipse.framScript.State;
    1414import com.framsticks.framclipse.framScript.VariableDeclaration;
     15import com.framsticks.framclipse.framScript.VariableDeclarations;
    1516import com.google.common.base.Predicate;
    1617import com.google.common.collect.Iterables;
     
    1920public class FramScriptResourceDescription extends DefaultResourceDescription {
    2021
     22        private Resource resource;
     23
    2124        public FramScriptResourceDescription(Resource resource,
    2225                        IDefaultResourceDescriptionStrategy resourceDescriptionStrategy) {
    2326                super(resource, resourceDescriptionStrategy);
     27                this.resource = resource;
    2428        }
    2529
     
    4953                if (input instanceof VariableDeclaration) {
    5054                        VariableDeclaration dec = (VariableDeclaration) input;
    51                         return dec.eContainer().eContainer() instanceof Code;
     55                        EObject decs = dec.eContainer();
     56                        return decs instanceof VariableDeclarations &&
     57                                        (decs.eContainer() instanceof Code ||
     58                                                        "inc".equals(resource.getURI().fileExtension()) &&
     59                                                        decs.eContainer().eContainer() == null);
    5260                }
    5361                return false;
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptImportUriResolver.java

    r437 r440  
    88public class FramScriptImportUriResolver extends ImportUriResolver {
    99        @Override
    10         public String apply(EObject from) {
     10        public String resolve(EObject from) {
    1111                if (from instanceof Header) {
    1212                        Header header = (Header) from;
    1313                        if (header.getName().equals("expdef:")) {
    14                                 return header.getValue() + ".expdef";
     14                                return header.getImportURI() + ".expdef";
    1515                        }
    1616                }
    17                 return super.apply(from);
     17                return super.resolve(from);
    1818        }
    1919}
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/scoping/FramScriptScopeProvider.java

    r438 r440  
    2020import org.eclipse.emf.ecore.EStructuralFeature;
    2121import org.eclipse.emf.ecore.resource.Resource;
     22import org.eclipse.emf.ecore.resource.ResourceSet;
    2223import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
    2324import org.eclipse.xtext.resource.EObjectDescription;
    2425import org.eclipse.xtext.resource.IEObjectDescription;
     26import org.eclipse.xtext.resource.IResourceDescription;
     27import org.eclipse.xtext.scoping.IGlobalScopeProvider;
    2528import org.eclipse.xtext.scoping.IScope;
    2629import org.eclipse.xtext.scoping.Scopes;
     
    3033import com.framsticks.framclipse.framScript.Block;
    3134import com.framsticks.framclipse.framScript.Code;
     35import com.framsticks.framclipse.framScript.Expdef;
     36import com.framsticks.framclipse.framScript.ForEachStatement;
     37import com.framsticks.framclipse.framScript.ForStatement;
    3238import com.framsticks.framclipse.framScript.FramScriptFactory;
    3339import com.framsticks.framclipse.framScript.Function;
    3440import com.framsticks.framclipse.framScript.GotoStatment;
     41import com.framsticks.framclipse.framScript.Header;
     42import com.framsticks.framclipse.framScript.IncludeDeclaration;
    3543import com.framsticks.framclipse.framScript.Invocation;
    3644import com.framsticks.framclipse.framScript.LabeledStatement;
    3745import com.framsticks.framclipse.framScript.Model;
     46import com.framsticks.framclipse.framScript.PropertyIncludeDeclaration;
    3847import com.framsticks.framclipse.framScript.ProposableFunctionImpl;
    3948import com.framsticks.framclipse.framScript.ProposableVariableDeclarationImpl;
    4049import com.framsticks.framclipse.framScript.QualifiedExpression;
     50import com.framsticks.framclipse.framScript.Show;
    4151import com.framsticks.framclipse.framScript.Statement;
    4252import com.framsticks.framclipse.framScript.VariableDeclaration;
    4353import com.framsticks.framclipse.framScript.VariableDeclarations;
    4454import com.framsticks.framclipse.framScript.VariableRef;
     55import com.framsticks.framclipse.resource.FramScriptResourceDescriptionManager;
    4556import com.framsticks.framclipse.script.ConstantProvider;
    4657import com.framsticks.framclipse.script.ExpressionTraverser;
     
    5465 * This class contains custom scoping description.
    5566 *
    56  * see : http://www.eclipse.org/Xtext/documentation/latest/xtext.html#scoping
    57  * on how and when to use it
    58  *
     67 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
     68 * on how and when to use it.
    5969 */
    6070public class FramScriptScopeProvider extends AbstractDeclarativeScopeProvider {
    61        
     71
    6272        private final ConstantProvider provider;
    63        
     73
    6474        private final ExpressionTraverser traverser;
    65        
     75
     76        @Inject
     77        private IGlobalScopeProvider globalScopeProvider;
     78
     79        @Inject
     80        private FramScriptResourceDescriptionManager descriptionManager;
     81
    6682        private Resource resource;
    67        
     83
    6884        private Map<String, IScope> typesScopes = Maps.newHashMap();
    6985        private Map<Type, IScope> functionScopes = Maps.newHashMap();
    7086        private Map<Type, IScope> fieldScopes = Maps.newHashMap();
    71        
     87
     88        private FramScriptImportUriResolver resolver = new FramScriptImportUriResolver();
     89
    7290        @Inject
    7391        public FramScriptScopeProvider(ConstantProvider provider, ExpressionTraverser traverser) {
     
    7795                initTypes();
    7896        }
    79        
     97
     98        @Override
     99        public IScope getScope(EObject context, EReference reference) {
     100                if (reference.getEContainingClass().getName().equals("VariableRef") &&
     101                                reference.getName().equals("var")) {
     102                        if (context instanceof VariableRef) {
     103                                QualifiedExpression parent = getParent((VariableRef) context);
     104                                if (parent != null) {
     105                                        return getScope(parent, reference);
     106                                }
     107                                EObject object = context;
     108                                while (object != null && !(object.eContainer() instanceof Block ||
     109                                                object.eContainer() instanceof ForStatement ||
     110                                                object.eContainer() instanceof ForEachStatement)) {
     111                                        object = object.eContainer();
     112                                }
     113                                Statement statement = (Statement) object;
     114                                EObject blockOrFor = object.eContainer();
     115
     116                                if (blockOrFor instanceof Block) {
     117                                        Block block = (Block) blockOrFor;
     118                                        return Scopes.scopeFor(precedingDeclarations(block, statement),
     119                                                        nextValidScope(block, reference));
     120                                } else
     121                                        return getScope(blockOrFor, reference);
     122                        } else if (context.eContainer() instanceof Block) {
     123                                Block block = (Block) context.eContainer();
     124                                List<VariableDeclaration> vars = precedingDeclarations(block, (Statement)context);
     125                                IScope outerScope = Scopes.scopeFor(vars, nextValidScope(block, reference));
     126                                if (context instanceof Block) {
     127                                        return outerScope;
     128                                }
     129                                return new SimpleScope(outerScope,
     130                                                super.getScope(context, reference).getAllElements());
     131                        }
     132                }
     133                return super.getScope(context, reference);
     134        }
     135
     136        private IScope nextValidScope(EObject context, EReference ref) {
     137                if (ref.getEContainingClass().getName().equals("VariableRef") &&
     138                                ref.getName().equals("var")) {
     139                        if (context instanceof Block) {
     140                                EObject parent = context.eContainer();
     141                                if (parent == null) {   // may happen in .inc files.
     142                                        return scope_VariableRef_var((Model)context, ref);
     143                                }
     144                                if (!(parent instanceof Block)) {
     145                                        return getScope(parent, ref);
     146                                }
     147                        }
     148                }
     149                return getScope(context, ref);
     150        }
     151
     152        private List<VariableDeclaration> precedingDeclarations(Block block, Statement statement){
     153                List<VariableDeclaration> vars = Lists.newArrayList();
     154                for (Statement stmt : block.getStatements()) {
     155                        // Everything after the statement is out of scope.
     156                        if (stmt == statement) {
     157                                break;
     158                        } else if (stmt instanceof VariableDeclarations) {
     159                                vars.addAll(((VariableDeclarations) stmt).getVars());
     160                        }
     161                }
     162                return vars;
     163        }
     164
    80165        protected void initTypes() {
    81166                List<Function> allFunctions = Lists.newArrayList();
     
    116201                        scope = scope_Invocation_function(getFunction(inv), ref);
    117202                }
    118                 scope = filterByArgumentsCount(scope, inv.getArgs().size());
    119                 return scope;
     203                Show show = getShow(inv);
     204                IScope showScope = show == null ? IScope.NULLSCOPE :
     205                        new SimpleScope(filterByArgumentsCount(getScope(show, ref), inv.getArgs().size()));
     206                return new SimpleScope(showScope, filterByArgumentsCount(scope, inv.getArgs().size()));
    120207        }
    121208
     
    132219        }
    133220
    134         private IScope filterByArgumentsCount(IScope scope, int size) {
     221        protected IScope scope_Invocation_function(Show show, EReference ref) {
     222                return addAliases(new SimpleScope(showExpdefIncludes(show, ref)));
     223        }
     224
     225        /*
     226         * Make sure scope contains only function descriptions.
     227         */
     228        private List<IEObjectDescription> filterByArgumentsCount(IScope scope, int size) {
    135229                List<IEObjectDescription> filtered = Lists.newArrayList();
    136230                for (IEObjectDescription desc : scope.getAllElements()) {
     
    140234                        }
    141235                }
    142                 return new SimpleScope(filtered);
    143         }
    144        
     236                return filtered;
     237        }
     238
    145239        private IScope addAliases(IScope scope) {
    146240                Iterable<IEObjectDescription> contents = scope.getAllElements();
     
    155249        }
    156250
    157         protected IScope scope_VariableRef_var(VariableRef var, EReference ref) {
    158                 QualifiedExpression parent = getParent(var);
    159                 if (parent != null) {
    160                         return scope_VariableRef_var(parent, ref);
    161                 } else {
    162                         return scope_VariableRef_var(getBlock(var), ref);
    163                 }
    164         }
    165 
    166251        protected IScope scope_VariableRef_var(QualifiedExpression var, EReference ref) {
    167252                Type type = traverser.getLastType(var);
    168253                IScope scope = fieldScopes.get(type);
    169                 return scope != null ? scope : IScope.NULLSCOPE;
    170         }
    171        
     254                return new SimpleScope(nextValidScope(var.eContainer(), ref),
     255                                scope != null ? scope.getAllElements() : new ArrayList<IEObjectDescription>());
     256        }
     257
    172258        protected IScope scope_VariableRef_var(Block block, EReference ref) {
     259                // Scope for Blocks is constructed earlier in getScope, so we stop here.
     260                return IScope.NULLSCOPE;
     261        }
     262
     263        protected IScope scope_VariableRef_var(ForStatement fs, EReference ref) {
    173264                List<VariableDeclaration> vars = Lists.newArrayList();
    174                 for (Statement stmt : block.getStatements()) {
    175                         if (stmt instanceof VariableDeclarations) {
    176                                 vars.addAll(((VariableDeclarations) stmt).getVars());
    177                         }
    178                 }
    179                 return Scopes.scopeFor(vars, getScope(block.eContainer(), ref));
    180         }
    181        
     265                Statement init = fs.getInit();
     266                if (init instanceof VariableDeclarations) {
     267                        vars.addAll(((VariableDeclarations)init).getVars());
     268                }
     269                return Scopes.scopeFor(vars, getScope(fs.eContainer(), ref));
     270        }
     271
     272        protected IScope scope_VariableRef_var(ForEachStatement fes, EReference ref) {
     273                List<VariableDeclaration> vars = Lists.newArrayList();
     274                if (fes.getDecl() == null)
     275                        return getScope(fes.eContainer(), ref);
     276                else {
     277                        vars.add(fes.getDecl());
     278                        return Scopes.scopeFor(vars, getScope(fes.eContainer(), ref));
     279                }
     280        }
     281
     282        /*
     283         * Blocks are handled specially in getScope,
     284         * and scope_VariableRef_var(Block, EReference) returns IScope.NULLSCOPE,
     285         * which breaks the chain of scopes,
     286         * so we have to ensure each unspecified scope_VariableRef_var call
     287         * is redirected to getScope in this class, instead of super.getScope.
     288         */
     289        protected IScope scope_VariableRef_var(EObject ctx, EReference ref) {
     290                EObject parent = ctx.eContainer();
     291                if (parent == null)
     292                        return IScope.NULLSCOPE;
     293                else
     294                        return getScope(parent, ref);
     295        }
     296
    182297        protected IScope scope_VariableRef_var(Function f, EReference ref) {
    183298                List<VariableDeclaration> vars = Lists.newArrayList();
     
    185300                return Scopes.scopeFor(vars, getScope(f.eContainer(), ref));
    186301        }
    187        
     302
    188303        protected IScope scope_VariableRef_var(Code code, EReference ref) {
    189304                List<VariableDeclaration> vars = Lists.newArrayList();
     
    193308                return Scopes.scopeFor(vars, getScope(code.eContainer(), ref));
    194309        }
    195        
     310
     311        private List<IEObjectDescription> showExpdefIncludes(Show show, EReference ref) {
     312                ArrayList<IEObjectDescription> result = Lists.newArrayList();
     313                // Get expdef header
     314                Header expdefHeader= null;
     315                for (Header h : show.getHeaders()) {
     316                        if ("expdef:".equals(h.getName())) {
     317                                        expdefHeader = h;
     318                                        break;
     319                        }
     320                }
     321                if (expdefHeader == null)
     322                        return result;
     323                // Find resource by name
     324                ResourceSet resourceSet = show.eResource().getResourceSet();
     325                String expdefFile = resolver.resolve(expdefHeader);
     326                Resource expdefResource = findResourceByName(resourceSet, expdefFile);
     327                if (expdefResource == null)
     328                        return result;
     329                // Mine include directives
     330                ArrayList<String> included = Lists.newArrayList();
     331                Expdef expdef = (Expdef) expdefResource.getContents().get(0);
     332                for (PropertyIncludeDeclaration pid : expdef.getPropertyImports())
     333                        included.add(pid.getImportURI());
     334                for (IncludeDeclaration id : expdef.getCode().getIncludes())
     335                        included.add(id.getImportURI());
     336                // Get globals
     337                for (String filename : included) {
     338                        Resource includedResource = findResourceByName(resourceSet, filename);
     339                        if (includedResource == null) {
     340                                String showURI = show.eResource().getURI().toString();
     341                                URI includeURI = URI.createURI(showURI.subSequence(
     342                                                0, showURI.lastIndexOf("/")+1) + filename);
     343                                includedResource = resourceSet.getResource(
     344                                                includeURI, true);
     345                                if (includedResource == null)
     346                                        continue;
     347                        }
     348                        IResourceDescription resourceDescription =
     349                                        descriptionManager.getResourceDescription(includedResource);
     350                        result.addAll(Lists.newArrayList(resourceDescription.getExportedObjectsByType(ref.getEReferenceType())));
     351                }
     352                return result;
     353        }
     354
     355        private Resource findResourceByName(ResourceSet resourceSet,
     356                        String filename) {
     357                for (Resource res : resourceSet.getResources()) {
     358                        if (res.getURI().toString().endsWith("/" + filename)) {
     359                                return res;
     360                        }
     361                }
     362                return null;
     363        }
     364
    196365        protected IScope scope_VariableRef_var(Model model, EReference ref) {
    197 //              IScope outerScope = delegateGetScope(model, ref).getOuterScope();
    198                 IScope types = typesScopes.get(getExtension(model));
    199                 return new SimpleScope(types.getAllElements());
     366                IScope outerScope = globalScopeProvider.getScope(model.eResource(), ref, null);
     367                if (model instanceof Show) {
     368                        outerScope = new SimpleScope(outerScope, showExpdefIncludes((Show)model, ref));
     369                }
     370                String ext = getExtension(model);
     371                if ("inc".equals(ext))  // There is no description for .inc in XML,
     372                        ext = "script"; // so we pretend it is a .script.
     373                IScope types = typesScopes.get(ext);
     374                return new SimpleScope(outerScope, types.getAllElements());
    200375        }
    201376
     
    211386                return Scopes.scopeFor(labels);
    212387        }
    213        
     388
     389        protected IScope scope_Property(Show show, EReference ref) {
     390                return new SimpleScope(delegateGetScope(show, ref), showExpdefIncludes(show, ref));
     391        }
     392
     393        protected IScope scope_State(Show show, EReference ref) {
     394                return new SimpleScope(delegateGetScope(show, ref), showExpdefIncludes(show, ref));
     395        }
     396
    214397        private Function createFunction(Element element) {
    215398                Function function = new ProposableFunctionImpl(element);
     
    233416                return global;
    234417        }
    235        
     418
    236419        private VariableDeclaration createVariableDeclaration(String name) {
    237420                VariableDeclaration var = FramScriptFactory.eINSTANCE.createVariableDeclaration();
     
    240423                return var;
    241424        }
    242        
     425
    243426        private QualifiedExpression getParent(QualifiedExpression expr) {
    244427                EStructuralFeature feature = expr.eContainingFeature();
    245428                if (feature.equals(QUALIFIED_EXPRESSION__CHILD)) {
    246429                        return (QualifiedExpression) expr.eContainer();
    247                 } else if (feature.equals(QUALIFIED_EXPRESSION__PARENT) 
     430                } else if (feature.equals(QUALIFIED_EXPRESSION__PARENT)
    248431                                || feature.equals(ARRAY_ELEMENT_EXPRESSION__ARRAY)) {
    249432                        return getParent((QualifiedExpression) expr.eContainer());
     
    252435                }
    253436        }
    254        
    255         private Block getBlock(EObject object) {
    256                 while (object != null && !(object instanceof Block)) {
    257                         object = object.eContainer();
    258                 }
    259                 return (Block) object;
    260         }
    261        
     437
    262438        private Function getFunction(EObject object) {
    263439                while (object != null && !(object instanceof Function)) {
     
    266442                return (Function) object;
    267443        }
    268        
     444
     445        private Show getShow(EObject object) {
     446                while (object != null && !(object instanceof Show)) {
     447                        object = object.eContainer();
     448                }
     449                return (Show) object;
     450        }
     451
    269452        private String getExtension(EObject object) {
    270453                return object.eResource().getURI().fileExtension();
    271454        }
    272        
     455
    273456}
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/XMLConstantProvider.java

    r438 r440  
    8585                for (File file : framscontext.getFiles()) {
    8686                        String ext = file.getPattern();
    87                         ext = ext.substring(ext.indexOf('.') + 1, ext.length());
     87                        ext = ext.substring(ext.lastIndexOf('.') + 1, ext.length());
    8888                        if (file.getCode() != null) {
    8989                                for (Context context : file.getCode().getContexts()) {
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/script/model/Element.java

    r437 r440  
    2121        @XStreamAlias("default")
    2222        @XStreamAsAttribute
    23         private Double def;
     23        private String def;
    2424
    2525        private String description;
     
    4747        }
    4848
    49         public Double getDef() {
     49        public String getDef() {
    5050                return def;
    5151        }
  • java/Framclipse/com.framsticks.framclipse/src/com/framsticks/framclipse/validation/FramScriptJavaValidator.java

    r437 r440  
     1/*
     2 * generated by Xtext
     3 */
    14package com.framsticks.framclipse.validation;
    25
     6/**
     7 * This class contains custom validation rules.
     8 *
     9 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
     10 */
     11public class FramScriptJavaValidator extends com.framsticks.framclipse.validation.AbstractFramScriptJavaValidator {
    312
    4 public class FramScriptJavaValidator extends AbstractFramScriptJavaValidator {
    5 
     13//      @Check
     14//      public void checkGreetingStartsWithCapital(Greeting greeting) {
     15//              if (!Character.isUpperCase(greeting.getName().charAt(0))) {
     16//                      warning("Name should start with a capital", MyDslPackage.Literals.GREETING__NAME);
     17//              }
     18//      }
    619}
Note: See TracChangeset for help on using the changeset viewer.