2016-09-26 12 views
0

ための効率的な方法:XTEXT:私はこのようなカスタムスコープにしようとしたカスタムスコープ

override def IScope getScope(EObject context, EReference reference) 

及びIはケースを使用する:

AbstractMyDslScopeProviderを拡張ファイルMyDslScopeProviderにおいて、 私はこの署名を用いて機能を実装しましたこのような

​​

が、私はそれがパラメータを持っているだというのが私の文法で機能を持っており、私たちは地元Vの内部で宣言することができますars。これは非常に解除され

 if (contextDecl instanceof function) { 

       val fun= contextDecl as function 
       val allContentsCurrFile = EcoreUtil2.getAllContentsOfType(fun,Constant) 
       EObjectsInScope.addAll(fun.params) 
       EObjectsInScope.addAll(allContentsCurrFile) 
       return Scopes.scopeFor(EObjectsInScope) 

      } 
else{ 
       val removeEobjects = newArrayList() 
       EObjectsInScope.addAll(EcoreUtil2.getAllContentsOfType(root,EObject)) 
       val funList= EcoreUtil2.getAllContentsOfType(root,function) as List<function> 
        for(function f: funList){ 
         removeEobjects.addAll(f.varDeclList) 
         removeEobjects.addAll(f.params.params) 
         removeEobjects.addAll(EcoreUtil2.getAllContentsOfType(f,Constant)) 
        } 

       EObjectsInScope.removeAll(removeEobjects) 

       return Scopes.scopeFor(EObjectsInScope) 

:私はので、私はこのような何かをした私は、彼らが唯一の関数の中で見えるようにしたい、それらのローカル変数やその関数のパラメータは、外から見えるであろうとしたくありませんすべてのEObjectを取得し、外部から見えたくないバールを削除するのは効率的です(時間がかかります)。 これをより効率的に行う方法がありますか?おかげさまで

+0

完全なコードを教えてください。削除したい要素が最初に「EObjectsInScope」でどのように終わったのか分かりません。 –

答えて

0

EDIT:あなたはローカル変数について話している場合あなたはまた、すべての"Xtext: IResourceScopeCache for Avoid expensive scope calculation"

まずに私の答えに興味があるかもしれません、あなたはおそらくそれらが宣言される前に、ローカル変数を使用して許可したくありません、例えば

function foo() { 
    x = x + 1; 
    int x = 0; 
} 

したがって、実際にはgetAllContentsOfType()を使用してあまりにも多くの作業をしています。

あなたの最適化を正確に達成しようとしていますか?関数内のコンテンツアシストのパフォーマンスが向上しましたか?小さな機能体で多数のモデルの速度が向上していますか?多くの大きな機能の速度が向上していますか?

時期尚早な最適化を避けるために、コードを管理しやすくし、実際に処理する必要がある作業負荷に比例しない場合にのみ速度を最適化することが重要です。あなたはホットスポットを見つけるためにプロファイラを使いましたか?パフォーマンスのボトルネックになると、人間の直観はかなり間違っている可能性があります。

とにかく、スコープのスピードを上げる必要があると仮定して、大量のワークロードがない場合は、最初のショットとしてTreeIteratorを使用して関数本体をトラバースして、 ecuneUtil2.getAllContainers(コンテキスト)の戻り値を使用して、prune()およびnext()を使用するときのガイドとして使用します。

I.e.

import static extension org.eclipse.xtext.EcoreUtil2.* 
// ... 

val predecessors = new ArrayList<EObject> 

val iterator = EcoreUtils.getAllContents(function, true) 
// Could be optimized further 
val descentGuide = context.allContainers.dropWhile[it != function].toList.reverseView.iterator 

var current = iterator.next 
var nextDescent = descentGuide.next 
while(current != context) { 
    // collect list with local variables here 
    predecessors += current 
    if(current == nextDescent) { 
     // Reached another ancestor of context - will look for the following ancestor next 
     nextDescent = descentGuide.next 
    } else { 
     iterator.prune 
    } 
    current = iterator.next 
} 

// Reverse so innermost declarations shadow outer declarations 
val localVariables = predecessors.filter(LocalVariableDeclaration).toList.reverseView 

私はコードをコンパイル/テストしませんでしたが、そのアイデアが明確になることを願っています。

whileループはいつか終了する必要があります.に到達しますが、whileループに&& iterator.hasNextを追加すると意味があります。

関連する問題