AbstractJavaParserContext.java revision cb5ffb7fdd56f1b768d25da330fa3b29ecb74eaf
1683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti/*
2683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * Copyright 2016 Federico Tomassetti
3683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti *
4683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * Licensed under the Apache License, Version 2.0 (the "License");
5683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * you may not use this file except in compliance with the License.
6683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * You may obtain a copy of the License at
7683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti *
8683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * http://www.apache.org/licenses/LICENSE-2.0
9683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti *
10683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * Unless required by applicable law or agreed to in writing, software
11683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * distributed under the License is distributed on an "AS IS" BASIS,
12683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * See the License for the specific language governing permissions and
14683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti * limitations under the License.
15683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti */
16683012de2a3a28358e848f8b145d462eb8b322baFederico Tomassetti
179c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettipackage com.github.javaparser.symbolsolver.javaparsermodel.contexts;
18d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
19d787c16867577551b1711d01f382a26af1d7a322Federico Tomassettiimport com.github.javaparser.ast.Node;
20c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassettiimport com.github.javaparser.ast.expr.Expression;
21c990d23490f5c4ac4322119b03d5951b63eef055Fred Lefévère-Laoideimport com.github.javaparser.ast.expr.FieldAccessExpr;
22c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassettiimport com.github.javaparser.ast.expr.MethodCallExpr;
231e7780e554428a10c73de88ca64e5933b2291593Federico Tomassettiimport com.github.javaparser.symbolsolver.core.resolution.Context;
249c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFactory;
259c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.model.declarations.ValueDeclaration;
269c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
279c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
289c53c2cbc607ea694438ade8630be0c155a33162Federico Tomassettiimport com.github.javaparser.symbolsolver.model.resolution.Value;
2908322b4714f672bed5ec424d3ace0a40da9ccd47Federico Tomassettiimport com.github.javaparser.symbolsolver.model.typesystem.Type;
301e7780e554428a10c73de88ca64e5933b2291593Federico Tomassettiimport com.github.javaparser.symbolsolver.resolution.SymbolDeclarator;
31d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
322568d9ebe91ceb0a13c98b16f99593cd22084efaFederico Tomassettiimport java.util.Optional;
332568d9ebe91ceb0a13c98b16f99593cd22084efaFederico Tomassetti
3499c0277ff34b0d97af1019ac91f20a19db364410Federico Tomassettiimport static com.github.javaparser.symbolsolver.javaparser.Navigator.getParentNode;
353e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti
36d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti/**
37e7704aa00835e056f7870bcb255db697f1f7ca25Federico Tomassetti * @author Federico Tomassetti
38d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti */
39d787c16867577551b1711d01f382a26af1d7a322Federico Tomassettipublic abstract class AbstractJavaParserContext<N extends Node> implements Context {
40d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
41d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti    protected N wrappedNode;
420e81f51c40996b42cb262dc2397126cee8f60965Federico Tomassetti    protected TypeSolver typeSolver;
43d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
446df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
456df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    /// Static methods
466df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
4749719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti
4803055f925053b3970b9d14cce3a3b9a0d002366dFederico Tomassetti    public static final SymbolReference<ValueDeclaration> solveWith(SymbolDeclarator symbolDeclarator, String name) {
4949719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti        for (ValueDeclaration decl : symbolDeclarator.getSymbolDeclarations()) {
5049719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            if (decl.getName().equals(name)) {
5149719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti                return SymbolReference.solved(decl);
5249719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti            }
5349719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti        }
5449719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti        return SymbolReference.unsolved(ValueDeclaration.class);
5549719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti    }
5649719b4acbe10e3714ceb4f7040acac34709f558Federico Tomassetti
576df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
586df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    /// Constructors
596df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
606df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti
616df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    public AbstractJavaParserContext(N wrappedNode, TypeSolver typeSolver) {
626df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti        if (wrappedNode == null) {
636df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti            throw new NullPointerException();
646df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti        }
656df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti        this.wrappedNode = wrappedNode;
666df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti        this.typeSolver = typeSolver;
676df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    }
686df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti
696df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
706df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    /// Public methods
716df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
726df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti
73bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti    @Override
74bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti    public boolean equals(Object o) {
75bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti        if (this == o) return true;
76bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti        if (o == null || getClass() != o.getClass()) return false;
77bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti
78c990d23490f5c4ac4322119b03d5951b63eef055Fred Lefévère-Laoide        AbstractJavaParserContext<?> that = (AbstractJavaParserContext<?>) o;
79bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti
80bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti        if (wrappedNode != null ? !wrappedNode.equals(that.wrappedNode) : that.wrappedNode != null) return false;
81bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti
82bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti        return true;
83bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti    }
84bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti
85bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti    @Override
86bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti    public int hashCode() {
87bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti        return wrappedNode != null ? wrappedNode.hashCode() : 0;
88bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti    }
89bb4473f790e2da86cdce011f7f867a51883aab48Federico Tomassetti
90535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti    @Override
9182eb44707b620803d424188a1eb8708fcaf093cbFederico Tomassetti    public Optional<Type> solveGenericType(String name, TypeSolver typeSolver) {
92535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti        Context parent = getParent();
93535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti        if (parent == null) {
94535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti            return Optional.empty();
95535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti        } else {
96535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti            return parent.solveGenericType(name, typeSolver);
97535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti        }
98535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti    }
99535dd7001046e740345e2d00cb27f13d69226521Federico Tomassetti
100d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti    @Override
101d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti    public final Context getParent() {
1023e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti        if (getParentNode(wrappedNode) instanceof MethodCallExpr) {
1033e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti            MethodCallExpr parentCall = (MethodCallExpr) getParentNode(wrappedNode);
104c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti            boolean found = false;
105c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti            if (parentCall.getArgs() != null) {
106c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti                for (Expression expression : parentCall.getArgs()) {
107c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti                    if (expression == wrappedNode) {
108c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti                        found = true;
109c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti                    }
110c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti                }
111c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti            }
112c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti            if (found) {
1133e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti                Node notMethod = getParentNode(wrappedNode);
11445175889553f49fd90a2860e9e6fa7869730db71Federico Tomassetti                while (notMethod instanceof MethodCallExpr) {
1153e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti                    notMethod = getParentNode(notMethod);
11645175889553f49fd90a2860e9e6fa7869730db71Federico Tomassetti                }
11745175889553f49fd90a2860e9e6fa7869730db71Federico Tomassetti                return JavaParserFactory.getContext(notMethod, typeSolver);
118c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti            }
119c08a0391fd27b2ecc75a264cce9eb4606d0f7b30Federico Tomassetti        }
1203e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti        Node notMethod = getParentNode(wrappedNode);
121cb5ffb7fdd56f1b768d25da330fa3b29ecb74eafFederico Tomassetti        while (notMethod instanceof MethodCallExpr || notMethod instanceof FieldAccessExpr) {
1223e4b012ca278ee33e9e02984367028cb1adf4bf5Federico Tomassetti            notMethod = getParentNode(notMethod);
12345175889553f49fd90a2860e9e6fa7869730db71Federico Tomassetti        }
12445175889553f49fd90a2860e9e6fa7869730db71Federico Tomassetti        return JavaParserFactory.getContext(notMethod, typeSolver);
125d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti    }
126d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti
1276df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
1286df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    /// Protected methods
1296df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    ///
1306df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti
1316df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    protected Optional<Value> solveWithAsValue(SymbolDeclarator symbolDeclarator, String name, TypeSolver typeSolver) {
1326df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti        return symbolDeclarator.getSymbolDeclarations().stream()
1336df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti                .filter(d -> d.getName().equals(name))
1346df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti                .map(d -> Value.from(d))
1356df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti                .findFirst();
1366df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti    }
1376df1aa26f75ff0d716a1290007e2b63cc05001aeFederico Tomassetti
138d787c16867577551b1711d01f382a26af1d7a322Federico Tomassetti}
139